Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/193.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 检测到协同路由、异步DiffUtil和不一致性错误_Android_Kotlin_Android Recyclerview_Kotlin Coroutines_Android Diffutils - Fatal编程技术网

Android 检测到协同路由、异步DiffUtil和不一致性错误

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

我在组合Kotlin流和异步DiffUtil时遇到问题

我的RecyclerView.Adapter中有此函数,它在计算线程上计算DiffUtil并在主线程上向RecyclerView发送更新:

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)
    }
}