Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IndexOutOfBoundsException when calling getTab() #20

Closed
cooltey opened this issue Oct 24, 2018 · 16 comments
Closed

IndexOutOfBoundsException when calling getTab() #20

cooltey opened this issue Oct 24, 2018 · 16 comments
Assignees
Labels

Comments

@cooltey
Copy link

cooltey commented Oct 24, 2018

Steps to reproduce:

  1. Have 20+ tabs opened
  2. Scroll up to the top of tab list
  3. Click on the "x" button to close tab
  4. After closing ~10 tabs, try to scroll down.

Stacktrace:

java.lang.IndexOutOfBoundsException: Index: 15, Size: 8
	at java.util.ArrayList.get(ArrayList.java:437)
	at de.mrapp.android.tabswitcher.model.TabSwitcherModel.getTab(TabSwitcherModel.java:1158)
	at de.mrapp.android.tabswitcher.TabSwitcher.getTab(TabSwitcher.java:1482)
	at de.mrapp.android.tabswitcher.model.TabItem.create(TabItem.java:100)
	at de.mrapp.android.tabswitcher.iterator.ItemIterator.getItem(ItemIterator.java:134)
	at de.mrapp.android.tabswitcher.iterator.AbstractItemIterator.next(AbstractItemIterator.java:229)
	at de.mrapp.android.tabswitcher.layout.AbstractTabSwitcherLayout.calculatePositionsWhenDraggingToStart(AbstractTabSwitcherLayout.java:706)
	at de.mrapp.android.tabswitcher.layout.AbstractTabSwitcherLayout.onDrag(AbstractTabSwitcherLayout.java:1573)
	at de.mrapp.android.tabswitcher.layout.AbstractDragTabsEventHandler.notifyOnDrag(AbstractDragTabsEventHandler.java:342)
	at de.mrapp.android.tabswitcher.layout.AbstractDragTabsEventHandler.handleDrag(AbstractDragTabsEventHandler.java:675)
	at de.mrapp.android.tabswitcher.layout.AbstractDragTabsEventHandler.onDrag(AbstractDragTabsEventHandler.java:735)
	at de.mrapp.android.tabswitcher.gesture.AbstractTouchEventHandler.handleTouchEvent(AbstractTouchEventHandler.java:317)
	at de.mrapp.android.tabswitcher.gesture.TouchEventDispatcher.handleTouchEvent(TouchEventDispatcher.java:272)
	at de.mrapp.android.tabswitcher.TabSwitcher.onTouchEvent(TabSwitcher.java:1942)
	at android.view.View.dispatchTouchEvent(View.java:11722)
	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2955)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2636)
	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2961)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2650)
	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2961)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2650)
	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2961)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2650)
	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2961)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2650)
	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2961)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2650)
	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2961)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2650)
	at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:455)
	at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1828)
	at android.app.Activity.dispatchTouchEvent(Activity.java:3292)
	at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
	at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
	at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:417)
	at android.view.View.dispatchPointerEvent(View.java:11961)
	at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4790)
	at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4604)
	at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4142)
	at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4195)
	at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4161)
	at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4288)
	at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4169)
	at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4345)
	at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4142)
	at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4195)
	at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4161)
	at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4169)
	at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4142)
	at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6663)
	at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6637)
	at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6598)
	at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6766)
	at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186)
	at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
	at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:177)
	at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:6737)
	at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:6789)
	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:966)
	at android.view.Choreographer.doCallbacks(Choreographer.java:778)
	at android.view.Choreographer.doFrame(Choreographer.java:707)
	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:952)
	at android.os.Handler.handleCallback(Handler.java:789)
	at android.os.Handler.dispatchMessage(Handler.java:98)
	at android.os.Looper.loop(Looper.java:251)
	at android.app.ActivityThread.main(ActivityThread.java:6572)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
@michael-rapp
Copy link
Owner

Thanks for reporting this issue. I just tried to reproduce the crash you have reported, but unfortunately I wasn't able to do so. Do you know a way to reliably trigger the crash other than randomly removing/adding tabs and swiping around?

@cooltey
Copy link
Author

cooltey commented Oct 24, 2018

No, I don't have a way to reliably trigger the crash now.

@dbrant
Copy link
Contributor

dbrant commented Oct 31, 2018

To provide a little more context, we've started using this component in the official Wikipedia app, and have been seeing this crash very sporadically from our users, although we haven't been able to reproduce it ourselves.

It doesn't seem to be specific to any particular device or API version, and the actual "index out of bounds" numbers are highly variable (not just "Index: 15, Size: 8"). We'll keep trying to reproduce.

@michael-rapp
Copy link
Owner

Wow, I wasn't aware that this library is used in an app that popular. I will see, if I can make any guesses about what might go wrong in these cases by taking a deeper look at the code.

@dbrant
Copy link
Contributor

dbrant commented Nov 5, 2018

I have managed to reproduce the crash in your "example" app that is included in the repo. It happens if I repeatedly click near the bottom-right corner (which closes a tab that is off-screen at the bottom), and also keep clicking the "Undo" action in the snackbar, which is in the same location. If I do this a sufficient number of times very quickly, then scroll up, the crash occurs.

Here is a video that demonstrates my actions: https://youtu.be/AXCIDuQlNTY

@michael-rapp
Copy link
Owner

I was able to reproduce the crash that is shown in your video. Thank's for that!

However, I am not sure if this is actually the crash the stacktrace that was posted above corresponds to. This is because Logcat does not show an IndexOutOfBoundsException but a NullPointerException:

java.lang.NullPointerException: Attempt to invoke virtual method 'de.mrapp.android.tabswitcher.model.Tag de.mrapp.android.tabswitcher.model.AbstractItem.getTag()' on a null object reference
        at de.mrapp.android.tabswitcher.layout.AbstractTabSwitcherLayout.calculatePositionsWhenDraggingToStart(AbstractTabSwitcherLayout.java:708)
        at de.mrapp.android.tabswitcher.layout.AbstractTabSwitcherLayout.onDrag(AbstractTabSwitcherLayout.java:1573)
        at de.mrapp.android.tabswitcher.layout.AbstractDragTabsEventHandler.notifyOnDrag(AbstractDragTabsEventHandler.java:342)
        at de.mrapp.android.tabswitcher.layout.AbstractDragTabsEventHandler.handleDrag(AbstractDragTabsEventHandler.java:675)
        at de.mrapp.android.tabswitcher.layout.AbstractDragTabsEventHandler.onDrag(AbstractDragTabsEventHandler.java:735)
        at de.mrapp.android.tabswitcher.gesture.AbstractTouchEventHandler.handleTouchEvent(AbstractTouchEventHandler.java:317)
        at de.mrapp.android.tabswitcher.gesture.TouchEventDispatcher.handleTouchEvent(TouchEventDispatcher.java:272)
        at de.mrapp.android.tabswitcher.TabSwitcher.onTouchEvent(TabSwitcher.java:1963)
        at android.view.View.dispatchTouchEvent(View.java:11725)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2955)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2636)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2961)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2650)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2961)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2650)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2961)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2650)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2961)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2650)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2961)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2650)
        at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:445)
        at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1828)
        at android.app.Activity.dispatchTouchEvent(Activity.java:3292)
        at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
        at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:407)
        at android.view.View.dispatchPointerEvent(View.java:11964)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4776)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4590)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4128)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4181)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4147)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4274)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4155)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4331)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4128)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4181)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4147)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4155)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4128)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6642)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6616)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6577)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6745)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
2018-11-05 21:41:40.104 24555-24555/de.mrapp.android.tabswitcher.example E/AndroidRuntime:     at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
        at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:176)
        at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:6716)
        at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:6768)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
        at android.view.Choreographer.doCallbacks(Choreographer.java:723)
        at android.view.Choreographer.doFrame(Choreographer.java:652)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

@dbrant
Copy link
Contributor

dbrant commented Nov 5, 2018

Yes, I have seen this stack trace as well, but the original one also happens (with the same repro steps), perhaps less frequently.

@michael-rapp
Copy link
Owner

Okay, so the stacktraces are probably related to each other. I will investigate further and will see how to possibly fix this.

@dbrant
Copy link
Contributor

dbrant commented Nov 5, 2018

One other update:
I can reproduce the crash even if I disable the Undo snackbar (never show it at all), and simply keep clicking to close tabs at the bottom right, then after a few clicks scroll up.
https://youtu.be/ELYBzx7cJ1g

@dbrant
Copy link
Contributor

dbrant commented Nov 5, 2018

OK! we have a much better minimal reproducible case (thanks @cooltey):

  • Scroll to the top of the tab list.
  • Start clicking the "x" button to close the tabs repeatedly, even while the previous tab is still animating away.
  • After a few tabs have animated away, scroll the list up.

https://youtu.be/0SimZWcE1O0

@michael-rapp
Copy link
Owner

I just published a new release 0.3.6. that provides kind of a workaround. Clicking the close buttons of tabs that are "stacked" at the bottom (or top) is now prevented (they shouldn't be clickable anyway).

This should prevent crashes as shown in the first two of your videos. However, this is not a proper fix of the underlying problem and it is still possible to cause a crash as shown in the third video (I was able to do so).

@michael-rapp
Copy link
Owner

I am now able to very reliably reproduce the issue and I know its cause. I just need to find a way to properly solve it...

@michael-rapp
Copy link
Owner

...and it is solved! At least I wasn't able to cause any more crashes when testing. The fix is included in release 0.3.7. It would be great if anyone could confirm that the issue is gone now.

@cooltey
Copy link
Author

cooltey commented Nov 6, 2018

Thanks, @michael-rapp!
I did a quick test and it looks great now! Will let @dbrant to confirm it as well.

@dbrant
Copy link
Contributor

dbrant commented Nov 6, 2018

That is looking much better! Thanks for the quick turnaround. I can no longer reproduce it myself, so I'm going to deploy to our Beta audience and see if any further reports come in.

wmfgerrit pushed a commit to wikimedia/apps-android-wikipedia that referenced this issue Nov 6, 2018
 - Looks like the owner fixed the issue!
 - michael-rapp/ChromeLikeTabSwitcher#20 (comment)

Change-Id: I09d771fbb6935666f3a2ee5c9182050ea889acb9
@michael-rapp
Copy link
Owner

michael-rapp commented Nov 6, 2018

Great! Thank you for the collaboration, @cooltey and @dbrant! I will close this issue for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants