作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我无法将 Kotlin Flows 和异步 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)
}
}
private fun updateConversationsList(conversations: List<ConversationsAdapter.Item>)
{
viewLifecycleOwner.lifecycleScope.launch {
(listConversations.adapter as ConversationsAdapter).updateDataset(conversations)
}
}
updateConversationsList()
在很短的时间内被多次调用,因为这个函数是由 Kotlin 的
Flows
调用的。喜欢
Flow<Conversation>
.
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder
错误。阅读
this thread我知道这是一个线程问题,我已经阅读了很多建议,例如
this one都说:更新 Adapter 数据集的线程和向 RecyclerView 分派(dispatch)更新的线程必须相同。
withContext(Dispatchers.Main) {
dataset = newDataset
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
var updateJob : Job? = null
private fun updateConversationsList(conversations: List<ConversationsAdapter.Item>)
{
updateJob?.cancel()
updateJob = viewLifecycleOwner.lifecycleScope.launch {
(listConversations.adapter as ConversationsAdapter).updateDataset(conversations)
}
}
withContext(Dispatchers.Main)
将在内部检查延续状态并且不会运行。
关于android - 协程、异步 DiffUtil 和不一致检测错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60118072/
在我的设置中,我试图有一个界面 Table继承自 Map (因为它主要用作 map 的包装器)。两个类继承自 Table - 本地和全局。全局的将有一个可变的映射,而本地的将有一个只有本地条目的映射。
Rust Nomicon 有 an entire section on variance除了关于 Box 的这一小节,我或多或少地理解了这一点和 Vec在 T 上(共同)变体. Box and Vec
我是一名优秀的程序员,十分优秀!