Eli*_*zer 8 concurrency diff android android-support-library android-recyclerview
DiffUtil
建议的文档建议DiffUtil.DiffResult
在后台线程上生成因为潜在的长计算时间.这对我来说似乎是一个坏主意,因为该线程可能在以下情况下对过时数据进行操作(假设list
访问是线程安全的):
list
并通知适配器list
与newList
这将对一些添加和移除一些的差异DiffUtil.calculateDiff
在后台调用并获取DiffResult
for list
和newList
,并将消息发送到将使用newList
和调用的主线程DiffResult.dispatchUpdatesTo
list
newList
被设置为新的数据源并且DiffResult.dispatchUpdatesTo
被运行导致基础数据的不一致视图+自DiffResults
计算以来丢失任何突变嗯,这不好,所以让我们从第3步开始改变:
newList
为新的数据源,DiffUtil.calculateDiff
在后台调用并获取DiffResult
for 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;
}
Run Code Online (Sandbox Code Playgroud)
但作为正确方式的载体,这可能很有用:)