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

Android11(SDK30)下RecyclerView仅滑动才显示条目 支付库导致刷新异常

问题根因

你遇到的RecyclerView数据更新后仅滑动才显示的问题,核心原因是支付库的异步回调默认执行在工作线程,你在回调中直接更新Adapter数据源、调用notify方法,没有切换到Android要求的UI主线程,导致RecyclerView的刷新消息没有被及时消费,直到触摸滑动触发UI事件队列处理时才完成刷新。

从你提供的代码来看具体问题点:

  1. querySkuDetailsAsync、queryPurchasesAsync等BillingClient的异步方法回调均执行在工作线程,你仅在onBillingSetupFinished外层加了主线程切换,回调内部的逻辑、delegate回调都没有切换到主线程,skuDetailsAvailable、purchaseSuccess等回调如果包含Adapter数据更新逻辑,就会触发非主线程更新UI的异常。
  2. 不需要调用recyclerview.invalidate()、forceLayout()这类方法刷新列表,只要在主线程正确调用Adapter的notify方法即可触发列表重绘。
修复方案

所有BillingClient异步回调(包括onPurchasesUpdated、acknowledgePurchase的回调等)中的逻辑、delegate触发逻辑,全部包裹主线程切换:

示例1:修复queryPurchasesAsync回调线程

billingClient!!.queryPurchasesAsync(BillingClient.SkuType.SUBS) { billingResults, queryPurchases ->
    mainAct?.runOnUiThread {
        // 原有所有queryPurchasesAsync回调内的逻辑全部移到此处
    }
}

示例2:修复getSkuDetails方法回调线程

billingClient!!.querySkuDetailsAsync(
    params.build()
) { billingResult, skuDetailsList ->
    if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
        if (skuDetailsList != null && skuDetailsList.isNotEmpty()) {
            mainAct?.runOnUiThread {
                delegate?.skuDetailsAvailable(skuDetailsList)
            }
        }
    }
}

同理,handlePurchases方法中所有触发delegate回调的位置,也要确保运行在主线程,避免业务层在回调中更新UI时出现线程问题。修复完成后,在skuDetailsAvailable回调中更新Adapter数据源,直接调用adapter.notifyDataSetChanged()即可正常触发列表刷新。

内容的提问来源于stack exchange,提问作者Endre Olah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 19:45:07