3
fun updateItems(
    newItems: List<T>?,
    itemSame: (T, T) -> Boolean,
    contentSame: (T, T) -> Boolean
) {
    val diffResult =
        DiffUtil.calculateDiff(DiffCalc(this.items, newItems!!, itemSame, contentSame))
    diffResult.dispatchUpdatesTo(this)
    items = newItems
}

Is it a good practice to suspend this using coroutines?

Abraham Mathew
  • 2,029
  • 3
  • 21
  • 42

1 Answers1

0

Depending on the number of items into the list, DiffUtil.calculateDiff can take a significant amount of time to execute (more than the 16ms allowed). Since you don't want to block the UI Thread, you'd better move this function call to another thread, then dispatch the result on the UI Thread.

Of course, you could use any technique you'd like : AsyncTask, RxJava Schedulers, or moving to another coroutine context with withContext(Dispatchers.Default). But this pattern is sooooo common that it has been implemented in the RecyclerView library : ListAdapter. When updating items of ListAdapterwith submitList, the difference is calculated on a background thread, you don't need to call calculateDiff and dispatchUpdatesTo anymore.

Thibault Seisel
  • 1,197
  • 11
  • 23
  • What if I am using RecyclerView.Adapter, the ListAdapter is extended from that class right. So is there a need to suspend when using RecyclerView.Adapter – Abraham Mathew Jul 25 '19 at 11:21
  • What do you mean by "need to suspend" ? If you meant "offload from the UI thread", then yes, you should. – Thibault Seisel Jul 25 '19 at 11:55
  • Yeah, does RecyclerView Adapter automatically perform that? – Abraham Mathew Jul 25 '19 at 11:58
  • No it doesn't, but `androidx.recyclerview.widget.ListAdapter` does, here is from the document for `ListAdapter.submitList` : If a list is already being displayed, a diff will be computed on a background thread, which will dispatch Adapter.notifyItem events on the main thread. – Thibault Seisel Jul 25 '19 at 12:05