The documentation for DiffUtil建议在后台线程上生成DiffUtil.DiffResult,因为可能需要很长的计算时间。这对我来说似乎是个坏主意,因为该线程可能在以下情况下对过时的数据进行操作(假设list访问是线程安全的):
将数据添加到list并通知适配器
需要将list替换为newList,这将有一些添加和一些删除的差异
在后台调用DiffUtil.calculateDiff,获取DiffResultlistnewList,并向将使用newList和调用DiffResult.dispatchUpdatesTo的主线程发送消息。
在处理该消息之前,用户对主线程执行一个操作,该操作会导致变异list
消息被处理,newList被设置为新的数据源,并且DiffResult.dispatchUpdatesTo被运行,导致底层数据的视图不一致,并且由于计算了DiffResults而丢失了任何突变。
那不好,所以我们从第3步开始改变:
newList设置为新的数据源,在后台调用DiffUtil.calculateDiff,获取DiffResultlistnewList,并向将调用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;
        }

但作为正确方法的载体,这可能是有用的:)

07-26 07:18