Status Update
Comments
st...@viber.com <st...@viber.com> #2
In another project, I encountered a similar exception under the same conditions:
java.lang.IndexOutOfBoundsException: Index: 4, Size: 4. It also was mentioned here
cl...@google.com <cl...@google.com> #3
Yeah the bug has to do with races introduced in 3.3.0 when we refactored
The class is now decoupled from any specific UI (it was previously coupled to RecyclerView), but now there are races between RecyclerView and AsyncPagingDataDiffer. Working on a fix right now.
ap...@google.com <ap...@google.com> #4
Project: platform/frameworks/support
Branch: androidx-main
Author: Clara Fok <
Link:
Fix race between presenter update and RV
Expand for full commit details
Fix race between presenter update and RV
In a previous CL aosp/3315349 we made previousPresenter reset within the computeDiff worker context to ensure that reset happens even if the refresh is interrupted. However, this introduced a race where RV work on main thread would be executed after presenter reset (meaning AsyncPagingDataDiffer now refers to the new presenter). This led to RV getting the wrong itemCount (it expects itemCount from old list rather than new list).
To prevent this, we need to ensure that RV work cannot be executed in between presenter reset and dispatchDiff. To do this, we move presenter reset back onto main thread to ensure no RV work can occur at least until presentPagingDataEvent completes.
Test: ./gradlew paging:paging-runtime:cC
Bug: 381024738
Relnote: "Fixed bug where RecyclerView throws IndexOutOfBoundsException when user scrolls while updating RecyclerView"
Change-Id: Id1f16a1e2cc0286458659d0bf63cf59ab3399b93
Files:
- M
paging/paging-runtime/src/androidTest/java/androidx/paging/AsyncPagingDataDifferTest.kt
- M
paging/paging-runtime/src/main/java/androidx/paging/AsyncPagingDataDiffer.kt
Hash: 837b71a5f455e57626b61c2ccc7fadce8a00b3bf
Date: Tue Dec 03 20:48:20 2024
pr...@google.com <pr...@google.com> #6
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.paging:paging-runtime:3.3.5
va...@gmail.com <va...@gmail.com> #7
Yes. It is only partially fixed. I upgraded to 3.3.5 and while I'm getting less crashes, I still get them as you can see in the screenshots.
ma...@kayak.com <ma...@kayak.com> #9
We're encountering the same issue in production. Although it happens infrequently, a fix would be greatly appreciated. I tried reproducing it in the sample project but was unsuccessful. Based on the logs and breadcrumbs, it appears to occur when navigating to a different activity while more results are still loading, and then returning to the previous screen while the local data source is being updated. Below are the stack traces in case they offer any insights:
androidx.paging.PageStore.checkIndex (PageStore.kt:56)
androidx.paging.PageStore.get (PageStore.kt)
androidx.paging.PagingDataPresenter.get (PagingDataPresenter.kt:278)
androidx.paging.AsyncPagingDataDiffer.getItem (AsyncPagingDataDiffer.kt:460)
androidx.paging.PagingDataAdapter.getItem (PagingDataAdapter.kt:302)
.....
androidx.recyclerview.widget.NestedAdapterWrapper.getItemViewType (NestedAdapterWrapper.java:146)
androidx.recyclerview.widget.ConcatAdapterController.getItemViewType (ConcatAdapterController.java:319)
androidx.recyclerview.widget.ConcatAdapter.getItemViewType (ConcatAdapter.java:178)
androidx.recyclerview.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition (RecyclerView.java:6594)
androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline (RecyclerView.java:6796)
cl...@google.com <cl...@google.com> #10
ja...@go-text.me <ja...@go-text.me> #11
We're unable to upgrade past 3.2.1 otherwise we get this crash. We've tried to upgrade since 3.3.1 but every version has this crash. We're unable to reproduce locally, but it's happening in the wild. As such I don't have a sample project that's able to reproduce. Is this on someone's radar to fix? Thank you.
Fatal Exception: java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionInboxSectionViewHolder{a814017 position=3 id=-1, oldPos=1, pLpos:1 scrap [attachedScrap] tmpDetached no parent} androidx.recyclerview.widget.RecyclerView{caf350 VFED..... ......I. 0,0-1080,1683 #7f0a0909 app:id/recycler_view_inbox}, adapter:com.textmeinc.textme3.ui.activity.main.inbox.adapter.v2.InboxAdapter2@17ca774, layout:androidx.recyclerview.widget.LinearLayoutManager@c6c2949, context:dagger.hilt.android.internal.managers.p@4c8d829
at androidx.recyclerview.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:6686)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6892)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6853)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6849)
at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2422)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1722)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1682)
at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:747)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:4683)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:4457)
at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:5011)
at android.view.View.layout(View.java:24461)
at android.view.ViewGroup.layout(ViewGroup.java:7412)
at androidx.swiperefreshlayout.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:625)
at android.view.View.layout(View.java:24461)
at android.view.ViewGroup.layout(ViewGroup.java:7412)
at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1961)
at android.view.View.layout(View.java:24461)
at android.view.ViewGroup.layout(ViewGroup.java:7412)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:374)
at android.widget.FrameLayout.onLayout(FrameLayout.java:312)
at android.view.View.layout(View.java:24461)
at android.view.ViewGroup.layout(ViewGroup.java:7412)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1818)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1584)
at android.view.View.layout(View.java:24461)
at android.view.ViewGroup.layout(ViewGroup.java:7412)
at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1961)
at android.view.View.layout(View.java:24461)
at android.view.ViewGroup.layout(ViewGroup.java:7412)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:374)
at android.widget.FrameLayout.onLayout(FrameLayout.java:312)
at android.view.View.layout(View.java:24461)
at android.view.ViewGroup.layout(ViewGroup.java:7412)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:374)
at android.widget.FrameLayout.onLayout(FrameLayout.java:312)
at android.view.View.layout(View.java:24461)
at android.view.ViewGroup.layout(ViewGroup.java:7412)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:374)
at android.widget.FrameLayout.onLayout(FrameLayout.java:312)
at android.view.View.layout(View.java:24461)
at android.view.ViewGroup.layout(ViewGroup.java:7412)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
at android.view.View.layout(View.java:24461)
at android.view.ViewGroup.layout(ViewGroup.java:7412)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:374)
at android.widget.FrameLayout.onLayout(FrameLayout.java:312)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:1330)
at android.view.View.layout(View.java:24461)
at android.view.ViewGroup.layout(ViewGroup.java:7412)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:4609)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:4031)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2919)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:10491)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1108)
at android.view.Choreographer.doCallbacks(Choreographer.java:866)
at android.view.Choreographer.doFrame(Choreographer.java:797)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1092)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8663)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
```
cl...@google.com <cl...@google.com> #12
ja...@go-text.me <ja...@go-text.me> #13
Yes we do, stacktrace is from app using 3.3.5
Description
Despite the fact that bug https://issuetracker.google.com/issues/343124454 is marked as fixed, it's still reproduced after updating from 3.2.1 to 3.3.4. I created a sample project to demonstrate it.
Steps to reproduce:
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 156(offset:156).state:1000 androidx.recyclerview.widget.RecyclerView{e95134d VFED..... ........ 0,367-1080,2205 #7f08016c app:id/recycler}, adapter:com.example.badsearch.MainRecyclerAdapter@be8de02, layout:androidx.recyclerview.widget.LinearLayoutManager@d575313, context:com.example.badsearch.MainActivity@3b66302 at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6364) at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288) at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:345) at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361) at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368) at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399) at android.os.Handler.handleCallback(Handler.java:958) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:230) at android.os.Looper.loop(Looper.java:319) at android.app.ActivityThread.main(ActivityThread.java:9063) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:588) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)