Going back in native stack cause crash on Android 7 if screen contains FlatList with refresh props (React Navigation related)
Description
Original issue: https://github.com/react-navigation/react-navigation/issues/12510
I have such react navigation structure: Home -> Details
When Details screen contains List components (FlatList, VirtualizedList) with refresh props such as onRefresh, refreshing or refreshControl = <RefreshController...> (React Native component) going back causes app crash and it happens only on Android 7. Other Android versions work as expected.
Can be reproduced on emulators and real devices
In logcat I have two errors:
- Exception in HostFunction: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
- java.lang.IndexOutOfBoundsException: getChildDrawingOrder() returned invalid index 1 (child count is 1)
Steps to reproduce
- Open example app
- Navigate to Details Screen
- Go back with ui or with hardware button
Snack or a link to a repository
https://github.com/Zao721/CrashOnGoingBackAndroid7
Screens version
^4.9.2, ^4.10.0
React Native version
78.1
Platforms
Android
JavaScript runtime
Hermes
Workflow
React Native (without Expo)
Architecture
Fabric (New Architecture)
Build type
Release mode
Device
Real device
Device model
Samsung Galaxy J2 Pro (Android 7.1.1), Android Emulator 7.1.1
Acknowledgements
Yes
I'm also experiencing this problem
Same here with a screen containing a ScrollView
java.lang.IndexOutOfBoundsException: getChildDrawingOrder() returned invalid index 1 (child count is 1)
at android.view.ViewGroup.getAndVerifyPreorderedIndex(ViewGroup.java:1766)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3729)
at android.view.View.draw(View.java:18588)
at android.view.View.updateDisplayListIfDirty(View.java:17563)
at android.view.View.draw(View.java:18347)
at android.view.ViewGroup.drawChild(ViewGroup.java:3946)
at com.facebook.react.views.view.a.drawChild(SourceFile:86)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3756)
at com.facebook.react.views.view.a.dispatchDraw(SourceFile:18)
at android.view.View.draw(View.java:18588)
at com.facebook.react.views.view.a.draw(SourceFile:60)
at android.view.View.updateDisplayListIfDirty(View.java:17563)
at android.view.View.draw(View.java:18347)
at android.view.ViewGroup.drawChild(ViewGroup.java:3946)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3756)
at android.view.View.updateDisplayListIfDirty(View.java:17558)
at android.view.View.draw(View.java:18347)
at android.view.ViewGroup.drawChild(ViewGroup.java:3946)
at androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild(SourceFile:136)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3732)
at android.view.View.updateDisplayListIfDirty(View.java:17558)
at android.view.View.draw(View.java:18347)
at android.view.ViewGroup.drawChild(ViewGroup.java:3946)
at com.swmansion.rnscreens.g.J(SourceFile:16)
at com.swmansion.rnscreens.g.B(SourceFile:1)
at com.swmansion.rnscreens.g$b.a(SourceFile:3)
at com.swmansion.rnscreens.g.F(SourceFile:26)
at com.swmansion.rnscreens.g.dispatchDraw(SourceFile:61)
at android.view.View.updateDisplayListIfDirty(View.java:17558)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3930)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3910)
at android.view.View.updateDisplayListIfDirty(View.java:17526)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:711)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:717)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:825)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:3209)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2996)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2584)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1569)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7301)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:930)
at android.view.Choreographer.doCallbacks(Choreographer.java:705)
at android.view.Choreographer.doFrame(Choreographer.java:640)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:916)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6816)
at java.lang.reflect.Method.invoke(Method.java)
Error: Exception in HostFunction: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7988)
at android.view.ViewRo...
at android.view.ViewRootImpl.checkThread(app:///ViewRootImpl.java:7988)
at android.view.ViewRootImpl.invalidateChildInParent(app:///ViewRootImpl.java:1392)
at android.view.ViewGroup.invalidateChild(app:///ViewGroup.java:5426)
at android.view.View.invalidateInternal(app:///View.java:14985)
at android.view.View.invalidate(app:///View.java:14949)
at android.view.ViewGroup.addView(app:///ViewGroup.java:4476)
at android.view.ViewGroup.addView(app:///ViewGroup.java:4417)
at com.swmansion.rnscreens.b.u(app:///SourceFile:31)
at com.swmansion.rnscreens.b.u(app:///SourceFile:60)
at com.swmansion.rnscreens.b.u(app:///SourceFile:60)
at com.swmansion.rnscreens.b.t(app:///SourceFile:8)
at com.swmansion.rnscreens.NativeProxy.notifyScreenRemoved(app:///SourceFile:24)
at com.facebook.jni.NativeRunnable.run(app:///Native Method)
at android.os.Handler.handleCallback(app:///Handler.java:751)
at android.os.Handler.dispatchMessage(app:///Handler.java:95)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(app:///SourceFile:1)
at android.os.Looper.loop(app:///Looper.java:154)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl.lambda$startNewBackgroundThread$2(app:///SourceFile:36)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl.b(app:///SourceFile:1)
at aD.run(app:///SourceFile:1)
at java.lang.Thread.run(app:///Thread.java:762)
at completeRoot(native)
at updateHostContainer(node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:6090:17)
at completeWork(node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:6180:28)
at completeUnitOfWork(node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:8298:28)
at performUnitOfWork(node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:8189:37)
at workLoopSync(node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:8080:54)
at renderRootSync(node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:8060:19)
at flushSyncWorkAcrossRoots_impl(node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:1924:48)
at processRootScheduleInMicrotask(node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:2015:32)
at scheduleMicrotask$argument_0(node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:2093:15)
Error Exception in HostFunction: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. (native) completeRoot node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:6090:16 updateHostContainer node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:6180:27 completeWork node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:8298:27 completeUnitOfWork node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:8189:36 performUnitOfWork node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:8080:53 workLoopSync node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:8060:18 renderRootSync node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:1924:47 flushSyncWorkAcrossRoots_impl node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:2015:31 processRootScheduleInMicrotask node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js:2093:14 anonymous
+1
+1
we're facing the same issue as well. it happens occasionally. this happens on ^4.11.0-beta.2
java.lang.IndexOutOfBoundsException: getChildDrawingOrder() returned invalid index 2 (child count is 2)
android.view.ViewGroup.getAndVerifyPreorderedIndex(ViewGroup.java:2122)
android.view.ViewGroup.dispatchDraw(ViewGroup.java:4416)
android.view.View.draw(View.java:26165)
android.view.View.updateDisplayListIfDirty(View.java:24922)
android.view.View.draw(View.java:25851)
android.view.ViewGroup.drawChild(ViewGroup.java:4670)
com.facebook.react.views.view.ReactViewGroup.drawChild(ReactViewGroup.java:975)
android.view.ViewGroup.dispatchDraw(ViewGroup.java:4443)
com.facebook.react.views.view.ReactViewGroup.dispatchDraw(ReactViewGroup.java:946)
android.view.View.draw(View.java:26165)
com.facebook.react.views.view.ReactViewGroup.draw(ReactViewGroup.java:937)
android.view.View.updateDisplayListIfDirty(View.java:24922)
android.view.View.draw(View.java:25851)
android.view.ViewGroup.drawChild(ViewGroup.java:4670)
android.view.ViewGroup.dispatchDraw(ViewGroup.java:4443)
android.view.View.updateDisplayListIfDirty(View.java:24909)
android.view.View.draw(View.java:25851)
android.view.ViewGroup.drawChild(ViewGroup.java:4670)
androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1312)
android.view.ViewGroup.dispatchDraw(ViewGroup.java:4419)
android.view.View.updateDisplayListIfDirty(View.java:24909)
android.view.View.draw(View.java:25851)
android.view.ViewGroup.drawChild(ViewGroup.java:4670)
com.swmansion.rnscreens.ScreenStack.performDraw(ScreenStack.kt:334)
com.swmansion.rnscreens.ScreenStack.access$performDraw(ScreenStack.kt:20)
com.swmansion.rnscreens.ScreenStack$DrawingOp.draw(ScreenStack.kt:347)
com.swmansion.rnscreens.ScreenStack.drawAndRelease(ScreenStack.kt:303)
com.swmansion.rnscreens.ScreenStack.dispatchDraw(ScreenStack.kt:313)
android.view.View.updateDisplayListIfDirty(View.java:24909)
android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4654)
android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4627)
android.view.View.updateDisplayListIfDirty(View.java:24844)
android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4654)
android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4627)
android.view.View.updateDisplayListIfDirty(View.java:24844)
android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4654)
android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4627)
android.view.View.updateDisplayListIfDirty(View.java:24844)
android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4654)
android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4627)
android.view.View.updateDisplayListIfDirty(View.java:24844)
android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4654)
android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4627)
android.view.View.updateDisplayListIfDirty(View.java:24844)
android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4654)
android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4627)
android.view.View.updateDisplayListIfDirty(View.java:24844)
android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4654)
android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4627)
android.view.View.updateDisplayListIfDirty(View.java:24844)
android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4654)
android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4627)
android.view.View.updateDisplayListIfDirty(View.java:24844)
android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4654)
android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4627)
android.view.View.updateDisplayListIfDirty(View.java:24844)
android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4654)
android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4627)
android.view.View.updateDisplayListIfDirty(View.java:24844)
android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4654)
android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4627)
android.view.View.updateDisplayListIfDirty(View.java:24844)
android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:744)
android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:753)
android.view.ThreadedRenderer.draw(ThreadedRenderer.java:859)
android.view.ViewRootImpl.draw(ViewRootImpl.java:6540)
android.view.ViewRootImpl.performDraw(ViewRootImpl.java:6146)
android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:5028)
android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:3545)
android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:11739)
android.view.Choreographer$CallbackRecord.run(Choreographer.java:1794)
android.view.Choreographer$CallbackRecord.run(Choreographer.java:1803)
android.view.Choreographer.doCallbacks(Choreographer.java:1295)
android.view.Choreographer.doFrame(Choreographer.java:1171)
android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1762)
android.os.Handler.handleCallback(Handler.java:959)
android.os.Handler.dispatchMessage(Handler.java:100)
android.os.Looper.loopOnce(Looper.java:249)
android.os.Looper.loop(Looper.java:337)
android.app.ActivityThread.main(ActivityThread.java:9486)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:636)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1004)
I also encountered the same problem:
"react-native-screens": "4.11.0",
"react-native": "0.78.2",
Hi, I'm attaching patch that should help with this issue. I created also a PR with those changes, but we're not sure if it will land in release as it may cause other problems.
Hey, thanks for the patch. Ran into this recently and that fixed it. About the other problems, I read the PR and it seems to be a concurrency issue? Do you know what side effects this could have? I haven't been able to cause anything.
@maciekstosio @kkafar is there any delay to getting this patch into a library version?
Hey, thanks for the patch. Ran into this recently and that fixed it. About the other problems, I read the PR and it seems to be a concurrency issue? Do you know what side effects this could have? I haven't been able to cause anything.
since we have no visibility on when a new release will come, did you face any side effect with this patch one month later? :)
Hey, thanks for the patch. Ran into this recently and that fixed it. About the other problems, I read the PR and it seems to be a concurrency issue? Do you know what side effects this could have? I haven't been able to cause anything.
since we have no visibility on when a new release will come, did you face any side effect with this patch one month later? :)
nothing yet, though im not sure its been enough to conclude much (not many people still use android 7). just to note, i changed the patch to only do the scheduling on android 7, so i wouldnt know about other versions
Hi, I'm attaching patch that should help with this issue. I created also a PR with those changes, but we're not sure if it will land in release as it may cause other problems.
I have the same problem (Android 7.1, react-native-screens 4.15.2, react-native 0.80.1) The patch helped - the problem disappeared
By any chance, was this issue resolved in recent 4.15.x versions? or is the patch for 4.11.1 the only way?