Android 检测到协同路由、异步DiffUtil和不一致性错误
我在组合Kotlin流和异步DiffUtil时遇到问题 我的RecyclerView.Adapter中有此函数,它在计算线程上计算DiffUtil并在主线程上向RecyclerView发送更新:Android 检测到协同路由、异步DiffUtil和不一致性错误,android,kotlin,android-recyclerview,kotlin-coroutines,android-diffutils,Android,Kotlin,Android Recyclerview,Kotlin Coroutines,Android Diffutils,我在组合Kotlin流和异步DiffUtil时遇到问题 我的RecyclerView.Adapter中有此函数,它在计算线程上计算DiffUtil并在主线程上向RecyclerView发送更新: suspend fun updateDataset(newDataset: List<Item>) = withContext(Dispatchers.Default) { val diff = DiffUtil.calculateDiff(object : DiffUtil
suspend fun updateDataset(newDataset: List<Item>) = withContext(Dispatchers.Default) {
val diff = DiffUtil.calculateDiff(object : DiffUtil.Callback()
{
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean
= dataset[oldItemPosition].conversation.id == newDataset[newItemPosition].conversation.id
override fun getOldListSize(): Int = dataset.size
override fun getNewListSize(): Int = newDataset.size
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean
= dataset[oldItemPosition] == newDataset[newItemPosition]
})
withContext(Dispatchers.Main) {
dataset = newDataset // <-- dataset is the Adapter's dataset
diff.dispatchUpdatesTo(this@ConversationsAdapter)
}
}
由于主线程(而且只有它)执行这两个操作,我怎么可能得到这个错误?您的差异正在加速。如果您的更新在短时间内出现两次,则可能发生以下情况:
Adapter has dataset 1 @Main
Dataset 2 comes
calculateDiff between 1 & 2 @Async
Dataset 3 comes
calculateDiff between 1 & 3 @Async
finished calculating diff between 1 & 2 @ Async
finished calculating diff between 1 & 3 @ Async
Dispatcher main starts handling messages
replace dataset 1 with dataset 2 using 1-2 diff @Main
replace dataset 2 with dataset 3 using 1-3 diff @Main - inconsistency
替代方案是1-3之间的差异可以在1-2之前完成,但问题保持不变。
当新的计算出现时,您必须取消正在进行的计算,并防止部署无效的差异,例如,在片段中存储作业引用:
var updateJob : Job? = null
private fun updateConversationsList(conversations: List<ConversationsAdapter.Item>)
{
updateJob?.cancel()
updateJob = viewLifecycleOwner.lifecycleScope.launch {
(listConversations.adapter as ConversationsAdapter).updateDataset(conversations)
}
}
var updateJob:Job?=无效的
私人娱乐更新会话列表(会话:列表)
{
updateJob?.cancel()
updateJob=viewLifecycleOwner.lifecycleScope.launch{
(listConversations.adapter作为ConversationsAdapter)。updateDataset(conversations)
}
}
如果您取消它,那么
withContext(Dispatchers.Main)
将在内部检查继续状态,并且不会运行。。1.您是否查看了ListAdapter
和DiffUtil.ItemCallback
?2.Square正在开发使用DiffUtil
和协同程序来实现您想要的功能,它可能是一个很好的参考源。感谢cycler,我不知道它看起来很有趣清楚的解释和干净的解决方案。非常感谢。
Adapter has dataset 1 @Main
Dataset 2 comes
calculateDiff between 1 & 2 @Async
Dataset 3 comes
calculateDiff between 1 & 3 @Async
finished calculating diff between 1 & 2 @ Async
finished calculating diff between 1 & 3 @ Async
Dispatcher main starts handling messages
replace dataset 1 with dataset 2 using 1-2 diff @Main
replace dataset 2 with dataset 3 using 1-3 diff @Main - inconsistency
var updateJob : Job? = null
private fun updateConversationsList(conversations: List<ConversationsAdapter.Item>)
{
updateJob?.cancel()
updateJob = viewLifecycleOwner.lifecycleScope.launch {
(listConversations.adapter as ConversationsAdapter).updateDataset(conversations)
}
}