簡體   English   中英

RecyclerView和DiffUtil - 並發夢魘

[英]RecyclerView and DiffUtil - A Concurrency Nightmare

DiffUtil的文檔建議在后台線程上生成DiffUtil.DiffResult ,因為可能DiffUtil.DiffResult很長的計算時間。 這對我來說似乎是一個壞主意,因為該線程可能在以下情況下運行在陳舊數據上(假設list訪問是線程安全的):

  1. 添加數據到list並通知適配器
  2. 需要用newList替換list ,這將有一些添加和一些刪除的差異
  3. 呼叫DiffUtil.calculateDiff背景並獲得DiffResultlistnewList ,並發布消息到主線程將使用newList並調用DiffResult.dispatchUpdatesTo
  4. 在處理該消息之前,用戶在主線程上執行導致突變list
  5. 消息被處理, newList被設置為新數據源並且運行DiffResult.dispatchUpdatesTo導致基礎數據的不一致視圖+自DiffResults計算以來任何突變的DiffResults

嗯,這不好,所以讓我們從第3步開始改變:

  1. newList設置為新數據源,在后台調用DiffUtil.calculateDiff並獲取DiffResult for listnewList ,並將消息發布到將調用DiffResult.dispatchUpdatesTo的主線程
  2. 在處理該消息之前,用戶對導致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;
        }

但作為正確方式的矢量,這可能是有用的:)

我最終堆疊更新以管理DiffUtil計算期間的用戶交互,並且仍然只訪問主線程中的數據集。

我在那里寫了: https//geoffreymetais.github.io/code/diffutil-threading/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM