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

CoroutineScope中调用RecyclerView的notifyDataSetChanged致App崩溃

RecyclerView更新崩溃问题解决方案

核心问题很明确:Android所有UI操作必须在主线程执行,你在Dispatchers.IO子线程里调用adapter.notifyDataSetChanged(),直接违反了Android的线程规则,导致App崩溃。

解决方法:切换到主线程更新UI

在协程中,用withContext(Dispatchers.Main)将UI更新逻辑切回主线程即可,修改后的代码示例如下:

// 获取Firebase Token后发起请求
CoroutineScope(Dispatchers.IO).launch {
    try {
        // 网络请求获取数据
        val response = apiService.getData(token)
        if (response.isSuccessful) {
            val dataList = response.body() ?: emptyList()
            // 将数据添加到集合
            yourDataCollection.addAll(dataList)
            
            // 切换到主线程更新RecyclerView
            withContext(Dispatchers.Main) {
                adapter.notifyDataSetChanged()
            }
        }
    } catch (e: Exception) {
        // 处理请求异常,若要提示用户也需切到主线程
        withContext(Dispatchers.Main) {
            Toast.makeText(context, "请求失败:${e.message}", Toast.LENGTH_SHORT).show()
        }
    }
}

针对Kotlin新手的额外建议

  • 优先使用viewModelScope代替自定义的CoroutineScope(Dispatchers.IO),它会自动和页面生命周期绑定,避免内存泄漏:
    // 在ViewModel中使用
    viewModelScope.launch(Dispatchers.IO) {
        // 网络请求逻辑...
        withContext(Dispatchers.Main) {
            adapter.notifyDataSetChanged()
        }
    }
    
  • 所有UI相关操作(包括更新Adapter、修改View属性等)都必须放在主线程,绝不可以在子线程执行。
  • 如果想提升更新效率,可以用notifyItemRangeInserted(startPosition, itemCount)代替notifyDataSetChanged(),只更新新增的数据项,避免全量刷新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 18:57:03