Flutter Android端如何修复“Billing service disconnected.”问题?
问题原因分析
- Android 13调试环境下的BillingClient重连循环:in_app_purchase插件3.1.5-3.1.10版本在Android 13物理设备的调试模式中,存在BillingClient断开后立即触发重连,重连完成后又再次断开的异常循环逻辑,导致日志反复打印,最终引发
DeadObjectException。 - 提前初始化单例的副作用:你实现的
IAPConnection单例会在首次访问时立即初始化InAppPurchase.instance,此时应用可能还未完成与Google Play Billing服务的稳定绑定,直接触发了插件的异常重连逻辑。 - 插件错误回调覆盖不全:当前版本插件的
purchaseStream错误回调未覆盖BillingClient连接层面的异常,无法捕获这种循环重连的错误场景。
修复方案
方案1:延迟初始化单例,避免提前触发连接
修改IAPConnection的初始化逻辑,仅在需要使用内购功能时才初始化InAppPurchase.instance,而非应用启动时就加载:
import 'package:flutter/foundation.dart'; import 'package:in_app_purchase/in_app_purchase.dart'; class IAPConnection { static InAppPurchase? _instance; static set instance(InAppPurchase value) { _instance = value; } static InAppPurchase get instance { _instance ??= InAppPurchase.instance; return _instance!; } // 供业务逻辑主动调用的初始化方法 static Future<void> init() async { if (_instance == null) { _instance = InAppPurchase.instance; // 提前检查Billing支持状态,减少后续重连触发概率 await _instance!.isAvailable(); } } }
使用时,在进入内购页面或触发内购操作前,先调用await IAPConnection.init();,而非App启动阶段就访问IAPConnection.instance。
方案2:手动控制BillingClient重连间隔
通过自定义逻辑控制重连频率,避免无限快速重连:
import 'package:in_app_purchase/in_app_purchase.dart'; class IAPManager { late InAppPurchase _iapInstance; bool _isReconnecting = false; final Duration _reconnectInterval = const Duration(seconds: 5); IAPManager() { _iapInstance = InAppPurchase.instance; _setupReconnectLogic(); } void _setupReconnectLogic() async { if (_isReconnecting) return; _isReconnecting = true; final isAvailable = await _iapInstance.isAvailable(); if (!isAvailable) { // 间隔指定时间后重试 Future.delayed(_reconnectInterval, () { _isReconnecting = false; _setupReconnectLogic(); }); } else { _isReconnecting = false; } } }
方案3:升级in_app_purchase插件版本
升级到插件的最新稳定版本,Google团队可能已修复Android 13调试环境下的重连循环问题。执行以下命令完成升级:
flutter pub upgrade in_app_purchase flutter clean && flutter pub get
方案4:调试模式下临时优化逻辑
在调试环境中添加条件判断,减少不必要的自动重连触发:
import 'package:flutter/foundation.dart'; import 'package:in_app_purchase/in_app_purchase.dart'; class IAPConnection { static InAppPurchase? _instance; static set instance(InAppPurchase value) { _instance = value; } static InAppPurchase get instance { if (_instance == null) { _instance = InAppPurchase.instance; // 调试模式下,仅在主动触发内购时执行连接检查 if (kDebugMode) { // 可跳过自动预连接逻辑 } } return _instance!; } }
验证方法
- 运行调试版本,观察日志是否不再反复打印
Billing service disconnected和Tried to call onBillingSetupFinished multiple times - 检查设备是否不再出现发热、卡顿现象
- 确认内购功能在调试模式下仍能正常使用
内容的提问来源于stack exchange,提问作者SePröbläm
相关产品推荐
相关产品推荐

