RecyclerView内部BUG:java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position

4057 ワード

一、BUG出現のログ:1.情况の说明:プロジェクトはちょうど1つの小さいバージョンを更新して、1つの上拉のリフレッシュとドロップダウンのロードするページを追加して、もとのRecyclerViewのリフレッシュのフレームワークは私がよくないと感じて、そこで1つ変えて、それからRCViewのデータに対して処理する时、処理の方式は以前と同じで、テスト机の上でテストしてもBUGが现れていないで、しかし上线の后で、BUGを爆発して、その上影响の人数はまだ多くて、そこで早速バグの原因を調べて解決しました.添付:BUGのログ
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 150(offset:150).state:153
    at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5504)
    at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5440)
    at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5436)
    at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2224)
    at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1551)
    at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1511)
    at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:595)
    at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3583)
    at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3312)
    at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1618)
    at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:4702)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
    at android.view.Choreographer.doCallbacks(Choreographer.java:686)
    at android.view.Choreographer.doFrame(Choreographer.java:619)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:7409)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)


2.BUG出現の原因:クラッシュLOGから見て、RcyclerView使用出現のバグに属するため、何度もgoogle関連を経て、原因をまとめました:データの除去とデータの増加を行う時、必ずAdapterの中のデータと除去のデータが一致することを保証します!これはどういう意味ですか.つまり、あなたのコレクションを更新した後、Adapterの新しいnotifyxxxxxメソッドを呼び出すと、adapterの更新予想結果と実際のコレクションの更新結果が異なると、異常が発生します.たとえば、removeに2つのデータが集合していますが、AdapterはnotifyItemRemoved(2)(ここでは3番目のデータを削除し、1つだけ削除したことを示します)だけで、この場合は古いデータと一致しません.もう1つはあなたがデータを増やして、あなたは10個のデータを集めて増加しますが、あなたのAdapterのnotifyは5個のデータしか増加していません.これもデータが一致していません.はい、以上の2つの状況を通じて、大体知っていますが、このデータが一致するのは実は数量が一致することを保証することです.つまりAdapterにはsizeがあり、あなたの集合にはsizeがあります.この2つのsizeは、Adapterのnotifyxxxxxを呼び出すときに同じままでなければなりません.ここを見て、あなたは分かったでしょう.3.ソリューション:ネット上にはこのようなソリューションがたくさんあります.私は最も信頼できるソリューションを選びました.LinearLayoutManagerというクラスを複写します.コードは以下の通りです.
public class RecyclerViewNoBugLinearLayoutManager extends LinearLayoutManager {
    public RecyclerViewNoBugLinearLayoutManager(Context context) {
        super( context );
    }

    public RecyclerViewNoBugLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super( context, orientation, reverseLayout );
    }

    public RecyclerViewNoBugLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super( context, attrs, defStyleAttr, defStyleRes );
    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        try {
        //try catch 
            super.onLayoutChildren( recycler, state );
        } catch (IndexOutOfBoundsException e) {
            e.printStackTrace();
        }

    }
}

これにより、RecyclerViewで発生する可能性のあるholder配列の境界Bugを解決することが効果的に回避される.
次のいくつかの文章は、このBUGに関する他のいくつかの処理です.①https://stackoverflow.com/questions/30458640/recyclerview-java-lang-indexoutofboundsexception-inconsistency-detected-inval ②http://www.cnblogs.com/fuyaozhishang/p/6991221.html