Android 整个应用程序中BillingClient的一个实例

Android 整个应用程序中BillingClient的一个实例,android,in-app-purchase,in-app-billing,Android,In App Purchase,In App Billing,我有一个有很多活动的应用程序。活动之一是显示购买选项 在billing library()的示例应用程序中,使用了BillingClientLifecycle和BillingManager,两者都与单个活动关联,因此在创建/销毁活动时打开/关闭连接 然而,在一个有很多活动的应用程序中,对于不同的活动单独执行此操作似乎并不理想。我还想在应用程序启动时检查订阅是否有效 我正在考虑在应用程序的应用程序子类中创建BillingClient。但是,如果我这样做,我只会打开BillingClient连接,而

我有一个有很多活动的应用程序。活动之一是显示购买选项

在billing library()的示例应用程序中,使用了BillingClientLifecycle和BillingManager,两者都与单个活动关联,因此在创建/销毁活动时打开/关闭连接

然而,在一个有很多活动的应用程序中,对于不同的活动单独执行此操作似乎并不理想。我还想在应用程序启动时检查订阅是否有效


我正在考虑在应用程序的应用程序子类中创建BillingClient。但是,如果我这样做,我只会打开BillingClient连接,而不会关闭它(因为其中没有onDestroy方法)。以前有没有人这样做过,遇到过什么问题?这是否也违反了最佳做法,是否会导致网络/性能出现任何问题?

看来这可以通过体系结构组件实现。即,在应用程序的OnCreate中,调用:

ProcessLifecycleOwner.get().lifecycle.addObserver(billingClient)


只需将billingClient注入到需要它的活动中。

'我建议不要将作为一个单例类,从中提供
billingClient
,并通过应用程序类进行初始化

为什么??因为,这样做,你们有机会在整个应用程序中使用时泄漏内存或对象


另一种方法是将此类类设为
LifecycleObserver
,这样,一旦您将其绑定到
活动/片段
,尽管它尊重生命周期,并相应地执行操作

我创建了如下这样的类,并在我的一些项目中使用(在这些项目中,它工作得非常好)

查看下面的课程:

InAppBilling.kt

以及如何使用它:

在您的
活动/片段的内部
中,您要使用
计费客户端

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对象从应用程序内客户端执行所需的操作

您需要做的就是将特定方法添加到appbilling类中,并在需要的地方使用该方法


中签出同一类BillingClient需要当前活动,因为它需要当前的窗口令牌向用户显示购买对话框。因此,每次活动更改时,窗口标记也会更改,因此您不能对singleton类执行此操作,因为在singleton类中,您正在泄漏活动引用,并且还提供了一个在应用程序会话中无效的窗口标记。

创建一个BaseActivity,并允许您的所有其他活动扩展基本活动。在BaseActivity中创建计费实例


不需要做it应用程序类。在应用程序中,当应用程序退出时,您不会得到事件。此外,如果将应用程序放在后台,应用程序实例仍然存在,因此连接将不必要地保持打开状态。

我在
billing-1.2.2-sources.jar
中通读了
BillingClientImpl.java
的源代码,我相信将
BillingClient
作为应用程序单例使用是安全的,即使这意味着永远不要调用
BillingClient.endConnection()

BillingClientImpl.java
在其构造函数中不需要/使用
活动
;它使用
上下文
,只需调用
Context.getApplicationContext()
来存储应用程序上下文。
launchBillingFlow
方法确实有一个
Activity
参数,但是没有存储该活动;它的唯一用途是调用
activity.startActivity(intent)
,并带有计费意图

BillingClient.startConnection
调用
context.registerReceiver
将自己的
BillingBroadcastReceiver
注册为
BroadcastReceiver
,然后调用
context.bindService
绑定服务连接。(同样,这两个调用都是针对应用程序上下文
mApplicationContext
,而不是针对任何特定的
活动执行的)

只要计费客户端在应用程序的生命周期内是必需的,在
Application.onCreate()
中调用
registerReceiver
bindService
以及从不调用
unregisterReceiver
unbindService
都是安全和可接受的


如果
registerReceiver
和/或
bindService
调用使用了
活动
上下文,这将是不安全的,因为
活动
被销毁时,
服务连接
会泄漏,但当应用程序被销毁时,其进程终止,所有的服务连接都会自动清理。

关于计费库的2.x更新版本,引用官方演示应用程序来源:

请注意,已创建到[playStoreBillingClient]的连接 使用applicationContext。这意味着该实例不可用 [活动]-特定的。而且因为它也不贵,所以它可以继续使用 在整个[应用程序]的生命周期内打开。所以不管是 (重新)为每个[活动]或[片段]创建,或为 应用程序的生命周期取决于选择


我想这也适用于第一个版本。

但是如果我们这样做,就不会有任何东西调用
BillingClient.endConnection
,对吗?安全吗?这似乎是安全的,因为当应用程序终止时,连接应该安全地断开,但我不能确定。我在整个应用程序中使用了一个连接,看起来很好,我没有遇到问题。我认为,如果您打开多个连接,则需要endConnection,因为存在资源/内存泄漏的可能性
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)