You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

安卓内购调用querySkuDetailsAsync后SkuDetailsResponseListener仅部分代码执行

问题根因与修复方案

核心原因

出现该问题90%以上的概率是线程非法操作触发未捕获异常,导致回调流程被强制中断,Google Play Billing库的querySkuDetailsAsync回调默认运行在后台子线程,安卓系统禁止在子线程执行UI更新操作,不同系统版本对子线程UI操作的检查严格度不同:前两行给textProduct赋值的操作刚好未触发线程校验,后续赋值操作触发CalledFromWrongThreadException后直接终止了回调逻辑,没有捕获异常的情况下不会打印相关报错。
其余可能的触发原因:

  • 控件未完成初始化或id匹配错误,textDesc/btnPrice为null,调用赋值逻辑时触发空指针异常
  • 返回的SkuDetails对象中description/price字段为空,触发空值赋值异常
  • 商品列表为空时直接取下标list[0]触发数组越界异常

修复代码

fun getProductDetails() {
    val productIds = mutableListOf<String>()
    productIds.add("product1")
    val getProductDetailQuery: SkuDetailsParams = SkuDetailsParams
        .newBuilder()
        .setSkusList(productIds)
        .setType(BillingClient.SkuType.INAPP)
        .build()

    billingClient.querySkuDetailsAsync(
        getProductDetailQuery
    ) { billingResult, list ->
        if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && list?.isNotEmpty() == true) {
            val itemInfo: SkuDetails = list[0]
            // 切换到主线程执行所有UI相关操作
            runOnUiThread {
                try {
                    textProduct.text = itemInfo.title
                    textDesc.text = itemInfo.description
                    btnPrice.text = itemInfo.price

                    btnPrice.setOnClickListener {
                        billingClient.launchBillingFlow(
                            this@BillingMainActivity,
                            BillingFlowParams.newBuilder()
                                .setSkuDetails(itemInfo)
                                .build()
                        )
                    }
                } catch (e: Exception) {
                    // 捕获异常打印定位问题
                    logBilling("回调执行异常: ${e.message}")
                    e.printStackTrace()
                }
            }
        } else {
            val error = BillingUtils.getBillingResponses(billingResult.responseCode)
            logBilling("getProductDetails error:$error")
        }
    }
}

额外排查项

  • 确认调用getProductDetails()的时机晚于控件初始化逻辑,所有涉及的控件id与布局文件中定义一致
  • 本地调试时可先打印itemInfo.description、itemInfo.price的取值,确认内购商品配置正常无空字段

内容的提问来源于stack exchange,提问作者Ahmet B.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 16:30:04