You need to enable JavaScript to run this app. Google Play Billing v3 初始化purchasesList null致内购查询异常
优惠活动
大模型
产品
解决方案
定价
更多

Google Play Billing v3 初始化purchasesList null致内购查询异常

核心根因
  • 问题完全来自BillingClient的调用时序错误,和Koin单例配置、Billing Library v3本身的逻辑无关。
  • 当BillingClient还未完成和Google Play服务的连接流程,也就是没有收到onBillingSetupFinished返回BillingResponseCode.OK的回调时,直接调用queryPurchases()是拿不到有效数据的:这个同步方法不会抛出异常,只会返回空的purchasesList,所有已购状态判断都会返回false。
  • 当前代码的执行路径刚好踩中了这个时序坑:
    • 首次进入SettingsFragment时,Koin初始化BillingHandler,在init块里同步调用ownsProduct()查询已购状态,此时BillingClient还没建立连接,自然拿到null的购买列表,最终doesUserOwnPremium()返回false。
    • 当用户点击购买入口触发startConnection()后,代码走到连接成功的回调分支,此时BillingClient处于isReady = true的有效连接状态,再调用ownsProduct()就能正常拉取到已购商品列表,自然能正确判定用户持有高级版权益。
现存代码的额外问题
  • doesUserOwnPremium()仅返回init阶段赋值的ownsPremium静态变量,这个值从初始化完成后就没有任何更新逻辑,哪怕后续BillingClient连上拿到了正确的已购状态,这个变量也不会同步刷新。
  • BillingClient的连接流程绑定在购买按钮的点击事件上,没有在页面初始化阶段主动发起连接,导致首次进入页面时所有计费相关查询都处于无效状态。
修复步骤
  • 移除BillingHandler init块中无效的同步查询逻辑,删掉ownsPremium = ownsProduct()这行代码——此时BillingClient未连接,查询没有任何实际意义。
  • 在onBillingSetupFinished的连接成功回调中,同步执行已购状态查询,更新ownsPremium变量:
    override fun onBillingSetupFinished(billingResult: BillingResult) {
        if(billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
            // 连接建立成功后再查询已购状态,保证数据有效
            ownsPremium = ownsProduct()
            loadSKUs()
        } else {
            Toast.makeText(context,"Something went wrong, please try again!", Toast.LENGTH_SHORT).show()
        }
    }
    
  • 在SettingsFragment拿到billingHandler实例后,不要同步读取doesUserOwnPremium()的结果就直接渲染UI,需要在BillingClient连接完成、已购状态更新后,通过回调通知Fragment刷新偏好项的启用状态,避免因为时序差拿到错误的初始值。
  • 在拿到BillingHandler实例后主动调用一次startConnection()发起连接,不要等用户点击购买按钮才触发连接流程,缩短状态就绪的等待时间。

内容的提问来源于stack exchange,提问作者Stelios Papamichail

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.09 15:45:09