The documentation for DiffUtil suggests creating a DiffUtil.DiffResult in the background thread due to potential lengthy calculations. This seems like a bad idea to me, because this thread may work with stale data in a situation like the following (assuming list access is thread safe):
- Add data to
list and notify adapter - You need to replace
list with newList , which will have different additions and some deletions - Call
DiffUtil.calculateDiff in the background and get DiffResult for list and newList , and post the message in the main thread that newList will use, and call DiffResult.dispatchUpdatesTo - Before processing this message, the user takes action on the main thread, which causes mutations in
list - The message is processed,
newList set as a new data source, and DiffResult.dispatchUpdatesTo triggered, causing an inconsistent representation of the underlying data + loss of any mutations, as DiffResults calculated
Itβs good that thereβs nothing good, so let the changes begin with step 3:
- Set
newList as the new data source, call DiffUtil.calculateDiff in the background and get the DiffResult for list and newList , and post the message in the main thread that will call DiffResult.dispatchUpdatesTo - Before processing this message, the user takes action in the main thread, which causes mutations in
newList , and notifies the adapter, causing data representation inconsistency, since DiffResult.dispatchUpdatesTo has not yet been called
There are a few more variations in this, but none of them are good. It seems that the only way to reliably use DiffUtil with a large DiffUtil to set the DiffUtil to either disable or queue all updates until DiffResult.dispatchUpdatesTo is called.
Did I miss something that would make it false?
source share