Recyclerview StaggeredGridLayoutManager 出现 IndexOutOfBoundsException 导致崩溃
镇楼图
在项目中使用
StaggeredGridLayoutManager
来实现瀑布流,万万没想到出现崩溃的情况,通过Bugly定位问题
java.util.ArrayList.get(ArrayList.java:437)
2 androidx.recyclerview.widget.StaggeredGridLayoutManager$Span.calculateCachedStart(StaggeredGridLayoutManager.java:2531)
3 androidx.recyclerview.widget.StaggeredGridLayoutManager$Span.getStartLine(StaggeredGridLayoutManager.java:2548)
4 androidx.recyclerview.widget.StaggeredGridLayoutManager.checkSpanForGap(StaggeredGridLayoutManager.java:410)
5 androidx.recyclerview.widget.StaggeredGridLayoutManager.hasGapsToFix(StaggeredGridLayoutManager.java:359)
6 androidx.recyclerview.widget.StaggeredGridLayoutManager.checkForGaps(StaggeredGridLayoutManager.java:282)
7 androidx.recyclerview.widget.StaggeredGridLayoutManager.onScrollStateChanged(StaggeredGridLayoutManager.java:317)
8 androidx.recyclerview.widget.RecyclerView.dispatchOnScrollStateChanged(RecyclerView.java:5197)
9 androidx.recyclerview.widget.RecyclerView.setScrollState(RecyclerView.java:1550)
10 androidx.recyclerview.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:5397)
11 android.view.Choreographer$CallbackRecord.run(Choreographer.java:1256)
12 android.view.Choreographer.doCallbacks(Choreographer.java:995)
13 android.view.Choreographer.lambda$new$0$Choreographer(Choreographer.java:233)
14 android.view.-$$Lambda$Choreographer$zXV0PrqwmpdPajenUBozqc6c8Hs.run(Unknown Source:2)
15 android.os.Handler.handleCallback(Handler.java:900)
16 android.os.Handler.dispatchMessage(Handler.java:103)
17 android.os.Looper.loop(Looper.java:219)
18 android.app.ActivityThread.main(ActivityThread.java:8387)
19 java.lang.reflect.Method.invoke(Native Method)
20 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
21 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
找到 StaggeredGridLayoutManager 错误的代码位置
void calculateCachedStart() {
final View startView = mViews.get(0);
final LayoutParams lp = getLayoutParams(startView);
mCachedStart = mPrimaryOrientation.getDecoratedStart(startView);
if (lp.mFullSpan) {
LazySpanLookup.FullSpanItem fsi = mLazySpanLookup
.getFullSpanItem(lp.getViewLayoutPosition());
if (fsi != null && fsi.mGapDir == LayoutState.LAYOUT_START) {
mCachedStart -= fsi.getGapForSpan(mIndex);
}
}
}
发现是取空集合导致的,然后定位到
//定位到此处报错 像个迂回办法通过try catch捕获该错误
StaggeredGridLayoutManager.onScrollStateChanged(StaggeredGridLayoutManager.java:317)
然后想了个迂回解决的办法
import android.content.Context;
import android.util.AttributeSet;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
/**
* author : lvi166
* date : 2021/1/7 15:36
* description : 重写 StaggeredGridLayoutManager 解决崩溃的情况
*/
public class ExpandStaggeredManager extends StaggeredGridLayoutManager {
public ExpandStaggeredManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public ExpandStaggeredManager(int spanCount, int orientation) {
super(spanCount, orientation);
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
try {
super.onLayoutChildren(recycler, state);
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 通过 try catch 捕捉错误
* @param state
*/
@Override
public void onScrollStateChanged(int state) {
try {
super.onScrollStateChanged(state);
}catch (Exception e){
e.printStackTrace();
}
}
}
然后试验了下,果然被捕获了并打印了出来
2021-01-07 16:01:31.082 20037-20037/com.jingling.housecloud W/System.err: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
2021-01-07 16:01:31.082 20037-20037/com.jingling.housecloud W/System.err: at java.util.ArrayList.get(ArrayList.java:437)
2021-01-07 16:01:31.082 20037-20037/com.jingling.housecloud W/System.err: at androidx.recyclerview.widget.StaggeredGridLayoutManager$Span.calculateCachedStart(StaggeredGridLayoutManager.java:2531)
2021-01-07 16:01:31.082 20037-20037/com.jingling.housecloud W/System.err: at androidx.recyclerview.widget.StaggeredGridLayoutManager$Span.getStartLine(StaggeredGridLayoutManager.java:2548)
2021-01-07 16:01:31.082 20037-20037/com.jingling.housecloud W/System.err: at androidx.recyclerview.widget.StaggeredGridLayoutManager.checkSpanForGap(StaggeredGridLayoutManager.java:410)
2021-01-07 16:01:31.082 20037-20037/com.jingling.housecloud W/System.err: at androidx.recyclerview.widget.StaggeredGridLayoutManager.hasGapsToFix(StaggeredGridLayoutManager.java:359)
2021-01-07 16:01:31.082 20037-20037/com.jingling.housecloud W/System.err: at androidx.recyclerview.widget.StaggeredGridLayoutManager.checkForGaps(StaggeredGridLayoutManager.java:282)
2021-01-07 16:01:31.082 20037-20037/com.jingling.housecloud W/System.err: at androidx.recyclerview.widget.StaggeredGridLayoutManager.onScrollStateChanged(StaggeredGridLayoutManager.java:317)
2021-01-07 16:01:31.083 20037-20037/com.jingling.housecloud W/System.err: at com.jingling.housecloud.widget.ExpandStaggeredManager.onScrollStateChanged(ExpandStaggeredManager.java:38)
2021-01-07 16:01:31.083 20037-20037/com.jingling.housecloud W/System.err: at androidx.recyclerview.widget.RecyclerView.dispatchOnScrollStateChanged(RecyclerView.java:5197)
2021-01-07 16:01:31.083 20037-20037/com.jingling.housecloud W/System.err: at androidx.recyclerview.widget.RecyclerView.setScrollState(RecyclerView.java:1550)
2021-01-07 16:01:31.083 20037-20037/com.jingling.housecloud W/System.err: at androidx.recyclerview.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:5397)
2021-01-07 16:01:31.083 20037-20037/com.jingling.housecloud W/System.err: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1031)
2021-01-07 16:01:31.083 20037-20037/com.jingling.housecloud W/System.err: at android.view.Choreographer.doCallbacks(Choreographer.java:854)
2021-01-07 16:01:31.083 20037-20037/com.jingling.housecloud W/System.err: at android.view.Choreographer.doFrame(Choreographer.java:785)
2021-01-07 16:01:31.083 20037-20037/com.jingling.housecloud W/System.err: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1016)
2021-01-07 16:01:31.083 20037-20037/com.jingling.housecloud W/System.err: at android.os.Handler.handleCallback(Handler.java:883)
2021-01-07 16:01:31.083 20037-20037/com.jingling.housecloud W/System.err: at android.os.Handler.dispatchMessage(Handler.java:100)
2021-01-07 16:01:31.083 20037-20037/com.jingling.housecloud W/System.err: at android.os.Looper.loop(Looper.java:224)
2021-01-07 16:01:31.083 20037-20037/com.jingling.housecloud W/System.err: at android.app.ActivityThread.main(ActivityThread.java:7520)
2021-01-07 16:01:31.083 20037-20037/com.jingling.housecloud W/System.err: at java.lang.reflect.Method.invoke(Native Method)
2021-01-07 16:01:31.083 20037-20037/com.jingling.housecloud W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
2021-01-07 16:01:31.083 20037-20037/com.jingling.housecloud W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
这个BUG导致的崩溃被运营给喷了
算是解决了吧 感谢 Bugly ,推荐大家接入一下(https://bugly.qq.com/v2/workbench/apps)
--