I'm implementing the Billing library into my app, I have encounter that for building the BillingClient I need to create an interface to listen for updates.
Problem is that this BillingClient needs to be a singleton, so I have added this inside my Singleton module in my app
@Module
@InstallIn(SingletonComponent::class)
class BillingModule {
@Provides
@Singleton
fun provideBillingClient(@ApplicationContext context: Context, purchasesUpdatedListener: PurchasesUpdatedListener): BillingClient {
return BillingClient.newBuilder(context)
.setListener(purchasesUpdatedListener)
.enablePendingPurchases()
.build()
}
@Provides
fun getPurchasesUpdatedListener(): PurchasesUpdatedListener = BillingUpdateListener()
}
Now, I have created this BillingUpdateListener class, this is because I need to propagate the results of this listener to my UI.
class BillingUpdateListener @Inject constructor(): PurchasesUpdatedListener {
private val _purchaseUpdateLiveData = MutableLiveData<PurchaseUpdate>()
val purchaseUpdateLiveData: LiveData<PurchaseUpdate> = _purchaseUpdateLiveData
override fun onPurchasesUpdated(
billingResult: BillingResult,
purchases: MutableList<Purchase>?
) {
_purchaseUpdateLiveData.value = PurchaseUpdate(billingResult, purchases)
}
}
data class PurchaseUpdate(
val billingResult: BillingResult,
val purchases: List<Purchase>?
)
ViewModel
@HiltViewModel
class MainViewModel @Inject constructor(
billingListener: BillingUpdateListener
) : ViewModel() {
val purchaseUpdateLiveData: LiveData<PurchaseUpdate> = billingListener.purchaseUpdateLiveData
}
MainActivity
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
@Inject
lateinit var billingClient: BillingClient
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Set status bar transparent
WindowCompat.setDecorFitsSystemWindows(window, true)
// Setup Listener
viewModel.purchaseUpdateLiveData.observe(this, { purchaseUpdate ->
Log.d("PurchaseUpdate", "Result: ${purchaseUpdate.billingResult}")
Log.d("PurchaseUpdate", "Purchases: ${purchaseUpdate.purchases}")
})
setContent { ... }
My problem is that the listener is successfully executing inside my BillingUpdateListener but unsuccessfully sent to my ViewModel -> UI
it always executes at this point
But never coming back to my viewmodel and UI to execute the logs.
I have tried StateFlow - SharedFlow and they also don't work, I'm assuming that maybe the problem relies on the injection or some problems with instances, but I find it hard to trace this issue without anything.
Any clue ?
