J'ai du mal à mettre ensemble Kotlin Flows et async DiffUtil.
J'ai cette fonction dans mon RecyclerView.Adapter qui calcule sur un thread de calcul un DiffUtil et envoie les mises à jour au RecyclerView sur le thread principal :
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)
}
}
J'appelle cette fonction depuis mon Fragment comme ceci :
private fun updateConversationsList(conversations: List<ConversationsAdapter.Item>)
{
viewLifecycleOwner.lifecycleScope.launch {
(listConversations.adapter as ConversationsAdapter).updateDataset(conversations)
}
}
updateConversationsList()
est appelée plusieurs fois dans un laps de temps très court, car cette fonction est appelée par la fonction de Kotlin Flows
comme Flow<Conversation>
.
Maintenant avec tout ça, j'ai parfois une java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder
erreur. Lecture du site ce fil Je comprends qu'il s'agit d'un problème d'enfilage et j'ai lu beaucoup de recommandations du genre celui-ci qui disent tous : le thread qui met à jour le jeu de données de l'adaptateur et le thread qui distribue les mises à jour au RecyclerView doivent être les mêmes.
Comme vous pouvez le constater, je respecte déjà ce principe en faisant :
withContext(Dispatchers.Main) {
dataset = newDataset
diff.dispatchUpdatesTo(this@ConversationsAdapter)
}
Puisque le fil principal, et lui seul, effectue ces deux opérations, comment est-il possible que j'obtienne cette erreur ?