The documentation for DiffUtil
建议在后台线程上生成DiffUtil.DiffResult
,因为可能需要很长的计算时间。这对我来说似乎是个坏主意,因为该线程可能在以下情况下对过时的数据进行操作(假设list
访问是线程安全的):
将数据添加到list
并通知适配器
需要将list
替换为newList
,这将有一些添加和一些删除的差异
在后台调用DiffUtil.calculateDiff
,获取DiffResult
和list
的newList
,并向将使用newList
和调用DiffResult.dispatchUpdatesTo
的主线程发送消息。
在处理该消息之前,用户对主线程执行一个操作,该操作会导致变异list
消息被处理,newList
被设置为新的数据源,并且DiffResult.dispatchUpdatesTo
被运行,导致底层数据的视图不一致,并且由于计算了DiffResults
而丢失了任何突变。
那不好,所以我们从第3步开始改变:
将newList
设置为新的数据源,在后台调用DiffUtil.calculateDiff
,获取DiffResult
和list
的newList
,并向将调用DiffResult.dispatchUpdatesTo
的主线程发送消息。
在处理该消息之前,用户在主线程上执行一个导致newList
发生突变的操作,并通知适配器,导致数据视图不一致,因为尚未调用DiffResult.dispatchUpdatesTo
。
有更多的变化,但没有一个是好的。对于大型数据集和变更集,可靠使用DiffUtil
的唯一方法似乎是禁用或排队所有更新,直到调用DiffResult.dispatchUpdatesTo
。
我是不是遗漏了什么会让上面说的都是假的?
最佳答案
查看BatchingListUpdateCallback。这是一个类,它包装了主回调,当列表发生多个更改时,batchinglistcallback只会通知一次主回调。
https://developer.android.com/reference/android/support/v7/util/BatchingListUpdateCallback.html
编辑
对不起,我的回答不对。
我查看了源代码diffutil。我看到,batchingListUpdateCallback无论如何都在dispatchUpdatesTo
方法中使用。
public void dispatchUpdatesTo(ListUpdateCallback updateCallback) {
final BatchingListUpdateCallback batchingCallback;
if (updateCallback instanceof BatchingListUpdateCallback) {
batchingCallback = (BatchingListUpdateCallback) updateCallback;
} else {
batchingCallback = new BatchingListUpdateCallback(updateCallback);
// replace updateCallback with a batching callback and override references to
// updateCallback so that we don't call it directly by mistake
//noinspection UnusedAssignment
updateCallback = batchingCallback;
}
但作为正确方法的载体,这可能是有用的:)