后台化后取消BillingClient交易,Android Activity未触发onResume()问题
问题描述
我的Android应用包含一笔消耗型交易,正常BillingClient购买流程运行正常,但在以下场景出现异常:显示Play Store购买弹窗时将应用后台化,恢复应用并取消购买后,Activity无法收到onResume()回调。
重现步骤
- 打开应用,选择购买商品;
- Play Store购买UI从屏幕底部滑出;
- 将应用后台化;
- 将应用前台化;
- Activity未收到
onResume(); - 点击购买UI对话框外部取消交易;
- Activity仍未收到
onResume()。
补充信息
该问题出现在Android 12、13、14设备上。后台化应用时,Activity会收到onPause()和onDestroy()回调,但前台化时从未收到onResume()、onStart()或onCreate()。应用出现在最近任务列表中,但无法绘制任何内容,不可见的应用会拦截所有触摸输入,导致用户觉得手机无响应。
请问是否有办法在应用后台化时关闭购买UI,从而避免Activity被销毁?
解决方案
1. 在Activity生命周期中主动终止购买流程
在发起购买的Activity里,跟踪购买状态,当应用进入后台(非配置变更类的onPause)时,主动关闭BillingClient连接,终止购买流程,让Play Store弹窗自动关闭。
代码示例(Kotlin):
private var isPurchaseInProgress = false private lateinit var billingClient: BillingClient override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) billingClient = BillingClient.newBuilder(this) .setListener { billingResult, purchases -> // 处理购买结果(成功/失败/取消) isPurchaseInProgress = false } .enablePendingPurchases() .build() } override fun onPause() { super.onPause() // 仅在应用真后台化(非屏幕旋转等配置变化)且有活跃购买时执行 if (!isChangingConfigurations && isPurchaseInProgress) { if (billingClient.isReady) { billingClient.endConnection() } isPurchaseInProgress = false } } override fun onResume() { super.onResume() // 恢复应用时重新连接BillingClient if (!billingClient.isReady) { billingClient.startConnection(object : BillingClientStateListener { override fun onBillingSetupFinished(result: BillingResult) { // 连接成功后的初始化操作 } override fun onBillingServiceDisconnected() { // 断开连接时自动重试 billingClient.startConnection(this) } }) } } // 启动购买流程的方法 private fun launchPurchaseFlow(skuDetails: SkuDetails) { val purchaseParams = BillingFlowParams.newBuilder() .setSkuDetails(skuDetails) .build() val result = billingClient.launchBillingFlow(this, purchaseParams) if (result.responseCode == BillingClient.BillingResponseCode.OK) { isPurchaseInProgress = true } }
2. 全局监听应用生命周期统一处理
如果应用多页面涉及内购,可在Application类中注册全局生命周期回调,统一管理BillingClient的连接状态:
class MyApplication : Application() { private var isAppInForeground = false private var billingClient: BillingClient? = null override fun onCreate() { super.onCreate() registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks { override fun onActivityPaused(activity: Activity) { isAppInForeground = false // 后台化时关闭BillingClient连接 billingClient?.takeIf { it.isReady }?.endConnection() } override fun onActivityResumed(activity: Activity) { isAppInForeground = true // 前台化时重新连接 billingClient?.let { client -> if (!client.isReady) { client.startConnection(object : BillingClientStateListener { override fun onBillingSetupFinished(result: BillingResult) {} override fun onBillingServiceDisconnected() { client.startConnection(this) } }) } } } // 其余生命周期方法留空实现 override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {} override fun onActivityStarted(activity: Activity) {} override fun onActivityStopped(activity: Activity) {} override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {} override fun onActivityDestroyed(activity: Activity) {} }) } // 提供全局BillingClient实例 fun getBillingClient(context: Context): BillingClient { if (billingClient == null) { billingClient = BillingClient.newBuilder(context) .setListener { billingResult, purchases -> // 全局购买结果处理 } .enablePendingPurchases() .build() } return billingClient!! } }
3. 完善购买异常处理
确保PurchasesUpdatedListener能正确捕获购买取消、失败等状态,及时重置isPurchaseInProgress标记;同时在Activity的onDestroy()中也主动关闭BillingClient连接,避免残留会话。
内容的提问来源于stack exchange,提问作者Bungles
相关产品推荐
相关产品推荐

