У меня проблемы со сборкой Kotlin Потоки и асинхронность c 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 s Flows
как Flow<Conversation>
.
Теперь, несмотря на все это, я иногда получаю ошибку java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder
. Чтение этой цепочки Я понимаю, что это проблема с многопоточностью, и я прочитал множество рекомендаций, таких как эта , которые все говорят: поток, который обновляет набор данных адаптера, и поток отправка обновлений в RecyclerView должна быть такой же.
Как вы можете видеть, я уже уважаю это, выполняя:
withContext(Dispatchers.Main) {
dataset = newDataset
diff.dispatchUpdatesTo(this@ConversationsAdapter)
}
Поскольку основной поток и только он выполняет эти две операции, как возможно, что я получаю эту ошибку