DiffResult 调度有时会导致 'Inconsistency detected. Invalid view holder adapter positionViewHolder' 错误
DiffResult dispatching lead to 'Inconsistency detected. Invalid view holder adapter positionViewHolder' error sometimes
我有一个接受两个列表的 RxJava2 Observable,计算它们的差异结果并将此数据发送到适配器。主线程上的适配器调度更新。
适配器中的调度代码:
public void dispatchStreams(List<StreamV3> streams, @Nullable DiffUtil.DiffResult diffResult) {
if (streams == null) return;
streamsList.clear();
streamsList.addAll(streams);
if (diffResult != null) {
diffResult.dispatchUpdatesTo(this);
}
}
我有时在某些设备上遇到 'Inconsistency detected. Invalid view holder adapter positionViewHolder' 错误。而且我无法弄清楚我的代码有什么问题。
Min SDK 21,Target SDK 26,RecyclerView 版本为 26.0.0。我知道扩展 LinearLayoutManager 并静默捕获此错误的解决方法,但这是一个糟糕的解决方案,我相信这里应该是更好的解决方案。
有人可以提供帮助吗?
我在这个 answer
中找到了这个问题的解决方案
问题似乎是由布局管理器上的 supportsPredictiveItemAnimations 属性 引起的。当我将其设置为 false 时,不再发生崩溃。
public class LinearLayoutManagerWrapper extends LinearLayoutManager {
public LinearLayoutManagerWrapper(Context context) {
super(context);
}
public LinearLayoutManagerWrapper(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public LinearLayoutManagerWrapper(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public boolean supportsPredictiveItemAnimations() {
return false;
}
}
在后台线程中将 Rx RV Diff 写入 运行 时遇到了这个问题。将 supportsPredictiveItemAnimations 设置为 false 是一种防止崩溃的解决方法,但并不能真正解决问题。
在我的案例中导致此异常的原因是后台线程中的数据集发生了变化。
// Diff and update the RV asynchronously
fun update(list: List<D>) {
Observable
.create<Pair<List<D>, DiffUtil.DiffResult>> {
// runs it asynchronous
val result = DiffUtil.calculateDiff(
diffCallback.apply {
newList = list
}
)
it.onNext(Pair(diffCallback.newList, result))
it.onComplete()
}
.takeUntil(destroyObservable) // observe the Lifecycle of the Frag
.subscribeOn(Schedulers.computation()) // run it async
.observeOn(AndroidSchedulers.mainThread()) // jump to the main thread
.subscribe {
// Set the new list
dataSet = it.first.map { it }
it.second.dispatchUpdatesTo(this@ListComponentAdapter)
}
}
我有一个接受两个列表的 RxJava2 Observable,计算它们的差异结果并将此数据发送到适配器。主线程上的适配器调度更新。
适配器中的调度代码:
public void dispatchStreams(List<StreamV3> streams, @Nullable DiffUtil.DiffResult diffResult) {
if (streams == null) return;
streamsList.clear();
streamsList.addAll(streams);
if (diffResult != null) {
diffResult.dispatchUpdatesTo(this);
}
}
我有时在某些设备上遇到 'Inconsistency detected. Invalid view holder adapter positionViewHolder' 错误。而且我无法弄清楚我的代码有什么问题。 Min SDK 21,Target SDK 26,RecyclerView 版本为 26.0.0。我知道扩展 LinearLayoutManager 并静默捕获此错误的解决方法,但这是一个糟糕的解决方案,我相信这里应该是更好的解决方案。
有人可以提供帮助吗?
我在这个 answer
中找到了这个问题的解决方案问题似乎是由布局管理器上的 supportsPredictiveItemAnimations 属性 引起的。当我将其设置为 false 时,不再发生崩溃。
public class LinearLayoutManagerWrapper extends LinearLayoutManager {
public LinearLayoutManagerWrapper(Context context) {
super(context);
}
public LinearLayoutManagerWrapper(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public LinearLayoutManagerWrapper(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public boolean supportsPredictiveItemAnimations() {
return false;
}
}
在后台线程中将 Rx RV Diff 写入 运行 时遇到了这个问题。将 supportsPredictiveItemAnimations 设置为 false 是一种防止崩溃的解决方法,但并不能真正解决问题。
在我的案例中导致此异常的原因是后台线程中的数据集发生了变化。
// Diff and update the RV asynchronously
fun update(list: List<D>) {
Observable
.create<Pair<List<D>, DiffUtil.DiffResult>> {
// runs it asynchronous
val result = DiffUtil.calculateDiff(
diffCallback.apply {
newList = list
}
)
it.onNext(Pair(diffCallback.newList, result))
it.onComplete()
}
.takeUntil(destroyObservable) // observe the Lifecycle of the Frag
.subscribeOn(Schedulers.computation()) // run it async
.observeOn(AndroidSchedulers.mainThread()) // jump to the main thread
.subscribe {
// Set the new list
dataSet = it.first.map { it }
it.second.dispatchUpdatesTo(this@ListComponentAdapter)
}
}