IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder

Main-zy發表於2017-10-19

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder異常處理

一般報這種錯誤有兩種情況:

第一種:list資料來源發生變化沒有及時重新整理adapter,也就是沒有及時notifyDataSetChanged()

第二種:以下情況的recycleView偶現錯誤,以下是第二種錯誤的解決方案

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{35b7b5f position=12 id=-1, oldPos=-1, pLpos:-1 no parent}
    at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5251)
    at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5433)
    at android.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:270)
    at android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:324)
    at android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:337)
    at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:344)
    at android.support.v7.widget.GapWorker.run(GapWorker.java:370)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:185)
    at android.app.ActivityThread.main(ActivityThread.java:6493)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:916)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:806)

具體也沒有報哪一行出錯,最終還是要google大神去修復

臨時解決方案:
建立一個LinearLayoutManagerWrapper繼承LinearLayoutManager,重寫onLayoutChildren方法,加個異常處理就行了

public class WrapContentLinearLayoutManager extends LinearLayoutManager {  
    public WrapContentLinearLayoutManager(Context context) {  
        super(context);  
    }  

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

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

    @Override  
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { 
        //這裡加個異常處理 ,經測試可以避免閃退,具體副作用暫時還沒有發現,可以作為臨時解決方案
        try {  
            super.onLayoutChildren(recycler, state);  
        } catch (IndexOutOfBoundsException e) {  
            e.printStackTrace();  
        }  
    }  
}  

然後recycleView中設定這個佈局就可以了,其他佈局樣式類似

mRecyclerView.setLayoutManager(new WrapContentLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)); 

相關文章