整个应用程序中BillingClient的一个实例
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了整个应用程序中BillingClient的一个实例相关的知识,希望对你有一定的参考价值。
我有一个有很多活动的应用程序。其中一项活动是显示购买选项。
在计费库(https://github.com/googlesamples/android-play-billing)的示例应用程序中,使用BillingClientLifecycle和BillingManager,它们都与单个活动相关联,因此在创建/销毁活动时打开/关闭连接。
但是,在具有许多活动的应用程序中,为不同的活动单独执行此操作似乎并不理想。我还想检查应用程序启动订阅是否有效。
我正在考虑在应用程序的Application子类中创建BillingClient。但是,如果我这样做,我只会打开BillingClient连接而不关闭它(因为那里没有onDestroy方法)。有没有人之前做过这件事并遇到任何问题?这也违反了最佳做法,是否会导致网络/性能出现问题?
看起来这可以通过架构组件来完成。即在你的应用程序的OnCreate中,调用:
ProcessLifecycleOwner.get()。lifecycle.addObserver(billingClient)
然后将billingClient注入需要它的活动中。
我读了BillingClientImpl.java
中billing-1.2.2-sources.jar
的来源,我相信使用BillingClient
作为应用程序单例是安全的,即使这意味着从不调用BillingClient.endConnection()
。
BillingClientImpl.java
在构造函数中不需要/使用Activity
;它使用Context
,它所做的只是调用context.getApplicationContext()
来存储应用程序上下文。 launchBillingFlow
方法确实有一个Activity
参数,但是没有存储活动;它唯一的目的是使用结算意图调用activity.startActivity(intent)
。
BillingClient.startConnection
称context.registerReceiver
将自己的BillingBroadcastReceiver
注册为BroadcastReceiver
,然后调用context.bindService
绑定服务连接。 (同样,这两个调用都是针对应用程序上下文mApplicationContext
执行的,而不是针对任何特定的Activity
执行。)
只要在应用程序的生命周期内需要结算客户端,在registerReceiver
中调用bindService
和Application.onCreate()
并且永远不会调用unregisterReceiver
或unbindService
是安全且可接受的。
如果registerReceiver
和/或bindService
调用使用Activity
上下文,这将是不安全的,因为当ServiceConnection
被销毁时Activity
会泄漏,但是当应用程序被销毁时,它的进程终止,并且它的所有服务连接都被自动清理。
“我建议不要创建一个从它提供BillingClient
并通过应用程序类初始化的Singleton类。”
为什么?因为,以这种方式,你有可能在使用整个应用程序时泄漏内存或对象。
替代方法是使这样的类成为LifecycleObserver
,这样一旦你将它绑定到你的Activity/Fragment
虽然尊重它的生命周期并做相应的事情。
我已经创建了如下所示的类,并在我的一些项目中使用(其中,它的工作非常好)。
看看下面的课程:
Inppbillingkkt
class InAppBilling(val lifecycle: Lifecycle, purchasesUpdatedListener: PurchasesUpdatedListener) :
LifecycleObserver,
PurchasesUpdatedListener by purchasesUpdatedListener,
BillingClientStateListener {
companion object {
const val TAG = "InAppBilling"
}
init {
lifecycle.addObserver(this)
}
private var mBillingClient: BillingClient? = null
private fun initClient(): BillingClient {
return BillingClient
.newBuilder(context) // You can provide application context here.
.setListener(this)
.build()
}
@OnLifecycleEvent(value = Lifecycle.Event.ON_CREATE)
fun connectionToBillingServer() {
mBillingClient = initClient()
mBillingClient?.startConnection(this)
}
@OnLifecycleEvent(value = Lifecycle.Event.ON_DESTROY)
fun disconnectFromBillingServer() {
mBillingClient?.endConnection()
lifecycle.removeObserver(this)
}
override fun onBillingServiceDisconnected() {
if (lifecycle.currentState == Lifecycle.State.CREATED) {
mBillingClient?.startConnection(this)
}
}
override fun onBillingSetupFinished(responseCode: Int) {
// Left out because "Unused"
}
}
以及如何消费它:
在你想要使用Activity/Fragment
的BillingClient
里面:
private var mBillingClient: InAppBilling? = null
//.. And inside of onCreate() method, you'll just need to initialize it like below:
mBillingClient = InAppBilling(this@Activity.lifecycle, this)
现在,您可以使用此billingClient对象从In-App客户端执行您想要的内容。
您需要做的就是将您的特定方法添加到InAppBilling类中,并将该方法用于您想要的位置。
查看this gist的同一课程。
创建BaseActivity并让所有其他活动扩展基本活动。在BaseActivity中创建计费实例。
不需要做应用程序类。与在应用程序中一样,当退出应用程序时,您不会收到任何事件。另外,如果你把app放在后台,应用程序实例仍然存在,因此连接将不必要地保持打开。
BillingClient需要当前活动,因为它需要当前窗口令牌来向用户显示购买对话框。因此,每次活动更改窗口令牌也会更改,因此您无法使用单例类执行此操作,因为在单例类中,您正在泄漏活动引用并且还提供单个窗口令牌,该令牌在您的应用程序会话中无效。
以上是关于整个应用程序中BillingClient的一个实例的主要内容,如果未能解决你的问题,请参考以下文章
BillingClient 始终返回 SERVICE_DISCONNECTED
退款客户应用内购买,但 BillingClient 仍然显示用户已购买?
BillingClient 和 PurchasesUpdateListener 类不可用
是否可以从 Xamarin Android 应用程序直接使用 Google Play BillingClient?
BillingClient.BillingClientStateListener.onBillingSetupFinished 被多次调用