一刁憋、BUG出現(xiàn)的日志:
1.情況描述:
項目剛更新了一個小版本,新增了一個上拉刷新和下拉加載的頁面,因為原來的RecyclerView的刷新框架我覺著不好,于是就換了一個撵儿,然后在對RCView數(shù)據(jù)處理的時候,處理的方式和以前是一樣的狐血,在測試機上測試也未出現(xiàn)BUG淀歇,但是上線之后,爆出了BUG匈织,而且影響人數(shù)還很多浪默,于是趕緊查了一下,出現(xiàn)的BUG的相關(guān)原因,并解決了它浴鸿。附上:BUG的Log
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出現(xiàn)的原因:
因為由崩潰LOG看井氢,屬于RcyclerView使用出現(xiàn)的bug,經(jīng)過多次google相關(guān),總結(jié)出了原因:
就是在進行數(shù)據(jù)移除和數(shù)據(jù)增加時岳链,務(wù)必要保證Adapter中的數(shù)據(jù)和移除的數(shù)據(jù)保持一致花竞!這是什么意思呢?就是如果你更新你的集合后掸哑,調(diào)用Adapter的新出現(xiàn)的notifyxxxx方法時约急,adapter 的更新預(yù)期結(jié)果和實際集合更新結(jié)果不同,那么就會出現(xiàn)異常了苗分。
例如: 比如你集合remove了兩條數(shù)據(jù)厌蔽,但是你Adapter只notifyItemRemoved(2)(這里表示移除第三條數(shù)據(jù),只移除了一條)摔癣,這種情況舊屬于數(shù)據(jù)不一致了奴饮。還有一種是你增加數(shù)據(jù),你集合增加10條數(shù)據(jù)择浊,但是你Adapter的notify只增加了5條數(shù)據(jù)戴卜,這也是數(shù)據(jù)不一致。
好了琢岩,通過以上兩種情況投剥,大概就知道了,這個數(shù)據(jù)一致其實說的是要保證數(shù)量一致担孔。就是說Adapter有個size江锨,你的集合有個size。這兩個size糕篇,在調(diào)用Adapter的notifyxxxx時候必須保持相同啄育。
看到此處,你應(yīng)該明白了吧拌消!
3.解決方案:
網(wǎng)上有很多解決此類的方案灸撰,我擇優(yōu)選擇了最靠譜的解決方案,就是復(fù)寫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可能出現(xiàn)的holder數(shù)組越界Bug浮毯。
下面幾篇文章,是另外幾篇關(guān)于此BUG的處理泰鸡。
①https://stackoverflow.com/questions/30458640/recyclerview-java-lang-indexoutofboundsexception-inconsistency-detected-inval
②http://www.cnblogs.com/fuyaozhishang/p/6991221.html