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