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

Android中使用Ketch库下载时RecyclerView不更新问题排查

解决Ketch下载任务RecyclerView不更新的问题

根据你的描述,已确认下载数据正常、submitList调用无误,但RecyclerView仍无法显示内容,可从以下关键方向排查修复:

1. 强制在主线程更新适配器

ListAdapter.submitList必须在主线程执行,虽然lifecycleScope默认绑定主线程,但flowOn(Dispatchers.IO)可能导致上游流切换线程后,下游collect的上下文出现偏差。修改observer()方法,确保UI更新操作在主线程执行:

private fun observer() {
    viewLifecycleOwner.lifecycleScope.launch {
        repeatOnLifecycle(Lifecycle.State.STARTED) {
            ketch.observeDownloads()
                .flowOn(Dispatchers.IO)
                .collect { downloads ->
                    withContext(Dispatchers.Main) {
                        // 生成新列表实例,避免引用不变导致DiffUtil不触发
                        adapterDownload.submitList(downloads.toList())
                    }
                }
        }
    }
}

2. 验证DownloadModel的equals/hashCode实现

你的DiffCallback中areContentsTheSame依赖oldItem == newItem,这要求DownloadModel必须正确重写equals和hashCode方法:

  • 如果DownloadModel是数据类,Kotlin会自动生成正确的比较逻辑,无需额外处理;
  • 如果是普通类,必须手动重写,确保所有影响UI显示的字段都被纳入比较:
class DownloadModel {
    var id: String = ""
    var fileName: String = ""
    var progress: Int = 0

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false
        other as DownloadModel
        if (id != other.id) return false
        if (fileName != other.fileName) return false
        if (progress != other.progress) return false
        return true
    }

    override fun hashCode(): Int {
        var result = id.hashCode()
        result = 31 * result + fileName.hashCode()
        result = 31 * result + progress
        return result
    }
}

3. 确保传入submitList的是新列表实例

如果ketch.observeDownloads()返回的是同一个列表引用(仅内部元素修改),ListAdapter会认为列表未变化,不会触发更新。通过toList()或ArrayList(downloads)生成新列表实例,强制触发DiffUtil计算:

adapterDownload.submitList(ArrayList(downloads))

4. 检查RecyclerView布局配置

  • 确认RecyclerView的高度设置正确,避免wrap_content在无初始数据时显示为空,或match_parent被其他View遮挡;
  • 检查Item布局的根View高度是否为wrap_content,避免内容被压缩隐藏。

额外验证步骤

  • 在adapterDownload.submitList()后添加日志,打印adapterDownload.currentList.size,确认适配器内部数据已更新;
  • 重写AdapterFile的onCurrentListChanged方法,观察列表变化是否被监听到:
override fun onCurrentListChanged(previousList: MutableList<DownloadModel>, currentList: MutableList<DownloadModel>) {
    super.onCurrentListChanged(previousList, currentList)
    Log.d("AdapterFile", "List updated: ${currentList.size} items")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 06:33:23