I have an app that has many activities. One of the activity is for showing purchase options.
In the sample apps for the billing library (https://github.com/googlesamples/android-play-billing), BillingClientLifecycle and BillingManager are used, both of which are associated to a single activity, so the connection is opened/closed when the activity is created/destroyed.
However in an app with many activities, it seems not ideal to do this separately for different activities. I also want to check on app start whether the subscriptions are valid.
I am thinking of creating the BillingClient in the app's Application subclass. However if I do this, I would only be opening the BillingClient connection and not closing it (as there's no onDestroy method in there). Has anyone done this before and hit any issues? Also is this against best practices and will it cause any issues with network / performance?
↳ com.android.billingclient.api.BillingClient. Main interface for communication between the library and user application code. It provides convenience methods for in-app billing. You can create one instance of this class for your application and use it to process in-app billing operations.
To acknowledge non-consumable purchases, use either BillingClient. acknowledgePurchase() from the Google Play Billing Library or Product. Purchases. Acknowledge from the Google Play Developer API.
With some apps, you can buy additional content or services within the app. We call these "in-app purchases." Here are some examples of in-app purchases: A sword that gives you more power in a game. A key that unlocks more features of an app.
It provides synchronous (blocking) and asynchronous (non-blocking) methods for many common in-app billing operations. It's strongly recommended that you instantiate only one BillingClient instance at one time to avoid multiple PurchasesUpdatedListener.onPurchasesUpdated (BillingResult, List) callbacks for a single event.
Initiates the billing flow for an in-app purchase or subscription. Initiates a flow to confirm the change of price for an item subscribed by the user. Constructs a new BillingClient.Builder instance. Returns the most recent purchase made by the user for each SKU, even if that purchase is expired, canceled, or consumed.
Exploring the Play Billing Library for Android. In-app billing is a powerful part of the Android framework that allows us to easily monetise our applications with in-app purchases and subscriptions. Google previously provided us with the in-app billing which allows us to implement this within our apps.
The documentation does not state the library as a replacement, but more as an easier way of implementing in-app billing. However, the library does allow you to reduce the amount of code required to implement in-app billing.
I read through the sources of BillingClientImpl.java
in billing-1.2.2-sources.jar
, and I believe it is safe to use BillingClient
as an application singleton, even if this means never calling BillingClient.endConnection()
.
BillingClientImpl.java
doesn't need/use an Activity
in its constructor; it uses a Context
, and all it does is call context.getApplicationContext()
to store the app context. The launchBillingFlow
method does have an Activity
parameter, but the activity isn't stored; its only purpose is to call activity.startActivity(intent)
with the billing intent.
BillingClient.startConnection
calls context.registerReceiver
to register its own BillingBroadcastReceiver
as a BroadcastReceiver
, then calls context.bindService
to bind a service connection. (Again, both of these calls are executed against the app context mApplicationContext
, not on any particular Activity
.)
As long as the billing client is required for the lifetime of the app, it's safe and acceptable to call registerReceiver
and bindService
in Application.onCreate()
and to never call unregisterReceiver
or unbindService
.
This would not be safe if the registerReceiver
and/or bindService
calls used an Activity
context, because the ServiceConnection
would leak when the Activity
was destroyed, but when the app is destroyed, its process terminates, and all of its service connections are automatically cleaned up.
Regarding the updated 2.x version of the billing library, a quote from the TrivialDriveKotlin official demo app BillingRepository sources:
Notice that the connection to [playStoreBillingClient] is created using the applicationContext. This means the instance is not [Activity]-specific. And since it's also not expensive, it can remain open for the life of the entire [Application]. So whether it is (re)created for each [Activity] or [Fragment] or is kept open for the life of the application is a matter of choice.
I guess this applies to the first version too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With