setDiffNewData异步diff数据时,可能导致IndexOutOfBoundsException
局部刷新时, 使用#setDiffNewData异步diff数据,此时在RecyclerView中下拉刷新(在BrvahAsyncDiffer进行异步diff的同时),会加载更早的数据,直接使用 getData().addAll(0, earlierDataList),可能导致IndexOutOfBoundsException。
2022-01-07 13:44:14.986, E/WTag-CrashHandler, java.lang.IndexOutOfBoundsException: Index: 4, Size: 40
at java.util.ArrayList.get(ArrayList.java:437)
at com.chad.library.adapter.base.diff.BrvahAsyncDiffer$submitList$1$result$1.areItemsTheSame(BrvahAsyncDiffer.kt:138)
at androidx.recyclerview.widget.DiffUtil.forward(DiffUtil.java:239)
at androidx.recyclerview.widget.DiffUtil.midPoint(DiffUtil.java:198)
at androidx.recyclerview.widget.DiffUtil.calculateDiff(DiffUtil.java:146)
at androidx.recyclerview.widget.DiffUtil.calculateDiff(DiffUtil.java:106)
at com.chad.library.adapter.base.diff.BrvahAsyncDiffer$submitList$1.run(BrvahAsyncDiffer.kt:128)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:929)
getData().addAll(0, earlierDataList)这个操作对数据源进行了更改,使得BrvahAsyncDiffer#submitList中的val oldList: List<T> = adapter.data 这个oldList数据发生了变化。
但是目前的场景,就是需要在已有数据之前添加earlierDataList,有其他方法吗?(不想整个替换数据源)
#setDiffNewData这个使用异步diff BrvahAsyncDiffer#submitList,应该是参考的官方的AsyncListDiffer#submitList。
但是官方的AsyncListDiffer#submitList,其中使用的是 unmodifiable list mReadOnlyList(AsyncListDiffer#getCurrentList返回的数据源也是这个,外部是不能修改的)。
但是BRVAH目前的使用中,AsyncListDiffer#submitList使用的是val oldList: List<T> = adapter.data,但是这个adapter.data在外部是可以对数据list进行add/remove之类的操作的。
这样就导致了当前issue的问题,在后台线程进行diff的过程中,其他地方主线程对adapter.data数据源进行add/remove操作之后,后台线程处理中的BrvahAsyncDiffer#submitList中的val oldList: List<T> = adapter.data就被修改了,导致getOldListSize是原先的数据总数,但是oldList#get(index)时是其他地方主线程更新后的数据list,list的数据已经变了,就有可能导致IndexOutOfBoundsException或者其他问题了。
@limuyang2 @CymChad
@limuyang2 @CymChad
作者应该已经不维护了😂
同样遇到这样的问题,请问下您解决了没有
#setDiffNewData这个使用异步diffBrvahAsyncDiffer#submitList,应该是参考的官方的AsyncListDiffer#submitList。 但是官方的AsyncListDiffer#submitList,其中使用的是 unmodifiable listmReadOnlyList(AsyncListDiffer#getCurrentList返回的数据源也是这个,外部是不能修改的)。但是BRVAH目前的使用中,
AsyncListDiffer#submitList使用的是val oldList: List<T> = adapter.data,但是这个adapter.data在外部是可以对数据list进行add/remove之类的操作的。这样就导致了当前issue的问题,在后台线程进行diff的过程中,其他地方主线程对
adapter.data数据源进行add/remove操作之后,后台线程处理中的BrvahAsyncDiffer#submitList中的val oldList: List<T> = adapter.data就被修改了,导致getOldListSize是原先的数据总数,但是oldList#get(index)时是其他地方主线程更新后的数据list,list的数据已经变了,就有可能导致IndexOutOfBoundsException或者其他问题了。
这个问题该怎么解决?
用這隻就能做同步了 setDiffNewData(@NonNull diffResult: DiffUtil.DiffResult, list: MutableList<T>)