Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StaggeredGridLayoutManager calculateCachedStart() IndexOutOfBoundsException

Hi I got error report from Fabric on my apps -> IndexOutOfBoundsException on StaggeredGridLayoutManager calculateCachedStart() method

There is many usage StaggeredGridLayoutManager on my apps. Any idea to fix this error or trace which one in my apps that cause this?

Using compile "com.android.support:recyclerview-v7:25.2.0

Fatal Exception: java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
       at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:260)
       at java.util.ArrayList.get(ArrayList.java:313)
       at android.support.v7.widget.StaggeredGridLayoutManager$Span.calculateCachedStart(StaggeredGridLayoutManager.java:2457)
       at android.support.v7.widget.StaggeredGridLayoutManager$Span.getStartLine(StaggeredGridLayoutManager.java:2474)
       at android.support.v7.widget.StaggeredGridLayoutManager.checkSpanForGap(StaggeredGridLayoutManager.java:410)
       at android.support.v7.widget.StaggeredGridLayoutManager.hasGapsToFix(StaggeredGridLayoutManager.java:359)
       at android.support.v7.widget.StaggeredGridLayoutManager.checkForGaps(StaggeredGridLayoutManager.java:284)
       at android.support.v7.widget.StaggeredGridLayoutManager.onScrollStateChanged(StaggeredGridLayoutManager.java:319)
       at android.support.v7.widget.RecyclerView.dispatchOnScrollStateChanged(RecyclerView.java:4596)
       at android.support.v7.widget.RecyclerView.setScrollState(RecyclerView.java:1371)
       at android.support.v7.widget.RecyclerView.cancelTouch(RecyclerView.java:2890)
       at android.support.v7.widget.RecyclerView.onTouchEvent(RecyclerView.java:2868)
       at android.view.View.dispatchTouchEvent(View.java:8593)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2493)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2157)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2495)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2171)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2495)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2171)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2530)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2171)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2530)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2171)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2530)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2171)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2530)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2171)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2530)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2171)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2530)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2171)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2530)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2171)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2530)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2171)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2530)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2171)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2530)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2171)
       at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2545)
       at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1818)
       at android.app.Activity.dispatchTouchEvent(Activity.java:2860)
       at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:71)
       at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2483)
       at android.view.View.dispatchPointerEvent(View.java:8799)
       at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4866)
       at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4681)
       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4146)
       at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4205)
       at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4165)
       at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4335)
       at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4173)
       at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4392)
       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4146)
       at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4205)
       at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4165)
       at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4173)
       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4146)
       at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6694)
       at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6668)
       at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6621)
       at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6853)
       at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:216)
       at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(InputEventReceiver.java)
       at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:192)
       at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:6812)
       at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:6879)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:804)
       at android.view.Choreographer.doCallbacks(Choreographer.java:607)
       at android.view.Choreographer.doFrame(Choreographer.java:574)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:790)
       at android.os.Handler.handleCallback(Handler.java:815)
       at android.os.Handler.dispatchMessage(Handler.java:104)
       at android.os.Looper.loop(Looper.java:210)
       at android.app.ActivityThread.main(ActivityThread.java:5833)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1113)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:879)

Thanks

like image 707
Eric Wijaya Avatar asked Jun 15 '17 15:06

Eric Wijaya


2 Answers

If your RecyclerView is in a Fragment and your Fragment is in ViewPager, and you didn't set viewpager.setOffscreenPageLimit(MAX_ITEM_SIZE), this crash will some times happen unexpectedly.

I was suffering same crashes. I can't reproduce it, and don't know why it would happen till now. But after I set the off-screen page limit, this crash goes away.

Wish it helps.

like image 97
HJWAJ Avatar answered Nov 17 '22 21:11

HJWAJ


It's part of StaggeredGridLayoutManager.java

  /**
     * Checks for gaps in the UI that may be caused by adapter changes.
     * <p>
     * When a full span item is laid out in reverse direction, it sets a flag which we check when
     * scroll is stopped (or re-layout happens) and re-layout after first valid item.
     */
    boolean checkForGaps() {
        if (getChildCount() == 0 || mGapStrategy == GAP_HANDLING_NONE || !isAttachedToWindow()) {
            return false;
        }
        final int minPos, maxPos;
        if (mShouldReverseLayout) {
            minPos = getLastChildPosition();
            maxPos = getFirstChildPosition();
        ....

For a workaround, we can prevent StaggeredGridLayoutmanager.hasGapsTofix() call (which is the reason for this crash).

staggeredGridLayoutmanager.gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_NONE

But this option disables unexpected gap handling.

like image 1
Zimin Byun Avatar answered Nov 17 '22 22:11

Zimin Byun