Android 衍射结果调度导致';检测到不一致。视图保持架适配器位置无效视图保持架';有时会出错

Android 衍射结果调度导致';检测到不一致。视图保持架适配器位置无效视图保持架';有时会出错,android,android-recyclerview,adapter,android-viewholder,Android,Android Recyclerview,Adapter,Android Viewholder,我有一个RxJava2 Observable,它获取两个列表,计算它们的差异结果,并将此数据发送给适配器。主线程上的适配器调度更新 适配器中的调度代码: public void dispatchStreams(List<StreamV3> streams, @Nullable DiffUtil.DiffResult diffResult) { if (streams == null) return; streamsList.clear(); stream

我有一个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);
    }
}
public void dispatchStreams(列表流,@Nullable DiffUtil.diffesult-diffesult){
if(streams==null)返回;
streamsList.clear();
streamsList.addAll(流);
如果(衍射结果!=null){
diffResult.dispatchUpdatesTo(本);
}
}
我已检测到“不一致”。某些设备上的视图保持架适配器位置无效视图保持架错误。我不知道我的代码出了什么问题。 Min SDK 21,Target SDK 26,RecyclerView版本为26.0.0。我知道扩展LinearLayoutManager并静默捕获此错误的解决方法,但这是一个糟糕的解决方案,我相信这里应该是更好的解决方案


有谁能提供帮助吗?

我在这篇文章中找到了解决这个问题的方法

问题似乎是由布局管理器上的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)
        }
}
//异步区分和更新RV
趣味更新(列表:列表){
可观察
.创造{
//异步运行它
val结果=DiffUtil.calculateDiff(
diffCallback.apply{
newList=列表
}
)
it.onNext(对(diffCallback.newList,result))
it.onComplete()
}
.takeUntil(destroyObservable)//观察碎片的生命周期
.subscribeOn(Schedulers.computation())//异步运行
.observeOn(AndroidSchedulers.mainThread())//跳转到主线程
.订阅{
//设置新列表
dataSet=it.first.map{it}
it.second.dispatchUpdatesTo(this@ListComponentAdapter)
}
}

检测到
不一致。无效的视图固定器适配器位置ViewHolder
?@Blackbelt,是的,我可以告诉您我们如何修复它,但我们不知道确切原因。这是一场考验和考验error@Blackbelt好的,我很高兴听到您的解决方案。如果原始问题或答案被删除,请在链接中包含代码片段。@Debanjan当然:)如果您需要predictiveItemAnimation怎么办?否则,您根本无法使用此功能!我也有同样的问题。我喜欢你的解决方案,但你能解释一下你是如何使用“可观测”的吗?也许“更新”可以是一个适配器方法,并返回可观察的内容,以便视图能够管理其处理。