The documentation for DiffUtil suggests generating the DiffUtil.DiffResult on a background thread because of potential long calculation times. This seems like a bad idea to me, because that thread could be operating on stale data in a situation like the following (assuming list access is thread safe):
list and notify adapterlist with newList which would have a diff of some additions and some removalsDiffUtil.calculateDiff in the background and get the DiffResult for list and newList, and post a message to the main thread that will use newList and call DiffResult.dispatchUpdatesTo
list
newList is set to be the new data source and DiffResult.dispatchUpdatesTo is run causing an inconsistent view of the underlying data + a loss of any mutations since the DiffResults were calculatedWell that's no good, so let's change starting from step 3:
newList as the new data source, call DiffUtil.calculateDiff in the background and get the DiffResult for list and newList, and post a message to the main thread that will call DiffResult.dispatchUpdatesTo
newList, and notifies adapter, causing an inconsistent view of data because DiffResult.dispatchUpdatesTo hasn't been called yetThere are more variations on this, but none are good. It seems like the only way to reliably use DiffUtil with a large dataset and changeset is to either disable or queue all updates until DiffResult.dispatchUpdatesTo is called.
Am I missing something that would make the above false?
I ended up stacking updates to manage user interaction during DiffUtil calculations and still accessing dataset in Main Thread only.
I wrote it there: https://geoffreymetais.github.io/code/diffutil-threading/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With