react-native-screens icon indicating copy to clipboard operation
react-native-screens copied to clipboard

feat: refactor snapshots when going back on Fabric

Open WoLewicki opened this issue 1 year ago • 1 comments

Description

PR refactoring snapshots when going back on Fabric on both platforms.

WoLewicki avatar May 14 '24 14:05 WoLewicki

Hi @WoLewicki! While I was testing all examples from FabricTestExample, I've stumbled onto one app crash while being on the branch from this PR. When I'm trying to run Test640 and I'm coming back to the previous screen (from the screen with TouchableOpacities), I'm getting crash with exception AssertionException and IndexOutOfBoundsException. Do you know what might be the cause of this? 🤔

Exception from Logcat
2024-05-20 15:56:17.375 23934-23978 unknown:SoftAssertions  com.fabrictestexample                E  Unhandled SoftException
                                                                                                    com.facebook.react.bridge.AssertionException: Expected to run on UI thread!
                                                                                                    	at com.facebook.react.bridge.SoftAssertions.assertCondition(SoftAssertions.java:37)
                                                                                                    	at com.facebook.react.bridge.UiThreadUtil.assertOnUiThread(UiThreadUtil.java:44)
                                                                                                    	at com.facebook.react.fabric.FabricUIManager.resolveView(FabricUIManager.java:921)
                                                                                                    	at com.swmansion.rnscreens.NativeProxy.notifyScreenRemoved(NativeProxy.kt:26)
                                                                                                    	at com.facebook.jni.NativeRunnable.run(Native Method)
                                                                                                    	at android.os.Handler.handleCallback(Handler.java:958)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                    	at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:205)
                                                                                                    	at android.os.Looper.loop(Looper.java:294)
                                                                                                    	at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:233)
                                                                                                    	at java.lang.Thread.run(Thread.java:1012)
2024-05-20 15:56:17.420 23934-23934 AndroidRuntime          com.fabrictestexample                D  Shutting down VM
2024-05-20 15:56:17.422 23934-23934 AndroidRuntime          com.fabrictestexample                E  FATAL EXCEPTION: main
                                                                                                    Process: com.fabrictestexample, PID: 23934
                                                                                                    java.lang.IndexOutOfBoundsException: getChildDrawingOrder() returned invalid index 1 (child count is 1)
                                                                                                    	at android.view.ViewGroup.getAndVerifyPreorderedIndex(ViewGroup.java:2100)
                                                                                                    	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4314)
                                                                                                    	at android.view.View.draw(View.java:23892)
                                                                                                    	at android.view.View.updateDisplayListIfDirty(View.java:22756)
                                                                                                    	at android.view.View.draw(View.java:23620)
                                                                                                    	at android.view.ViewGroup.drawChild(ViewGroup.java:4556)
                                                                                                    	at com.facebook.react.views.view.ReactViewGroup.drawChild(ReactViewGroup.java:873)
                                                                                                    	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4341)
                                                                                                    	at com.facebook.react.views.view.ReactViewGroup.dispatchDraw(ReactViewGroup.java:846)
                                                                                                    	at android.view.View.draw(View.java:23892)
                                                                                                    	at android.view.View.updateDisplayListIfDirty(View.java:22756)
                                                                                                    	at android.view.View.draw(View.java:23620)
                                                                                                    	at android.view.ViewGroup.drawChild(ViewGroup.java:4556)
                                                                                                    	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4341)
                                                                                                    	at android.view.View.updateDisplayListIfDirty(View.java:22747)
                                                                                                    	at android.view.View.draw(View.java:23620)
                                                                                                    	at android.view.ViewGroup.drawChild(ViewGroup.java:4556)
                                                                                                    	at androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1312)
                                                                                                    	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4317)
                                                                                                    	at android.view.View.updateDisplayListIfDirty(View.java:22747)
                                                                                                    	at android.view.View.draw(View.java:23620)
                                                                                                    	at android.view.ViewGroup.drawChild(ViewGroup.java:4556)
                                                                                                    	at com.swmansion.rnscreens.ScreenStack.performDraw(ScreenStack.kt:315)
                                                                                                    	at com.swmansion.rnscreens.ScreenStack.access$performDraw(ScreenStack.kt:15)
                                                                                                    	at com.swmansion.rnscreens.ScreenStack$DrawingOp.draw(ScreenStack.kt:327)
                                                                                                    	at com.swmansion.rnscreens.ScreenStack.drawAndRelease(ScreenStack.kt:282)
                                                                                                    	at com.swmansion.rnscreens.ScreenStack.dispatchDraw(ScreenStack.kt:298)
                                                                                                    	at android.view.View.updateDisplayListIfDirty(View.java:22747)
                                                                                                    	at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540)
                                                                                                    	at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513)
                                                                                                    	at android.view.View.updateDisplayListIfDirty(View.java:22712)
                                                                                                    	at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540)
                                                                                                    	at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513)
                                                                                                    	at android.view.View.updateDisplayListIfDirty(View.java:22712)
                                                                                                    	at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540)
                                                                                                    	at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513)
                                                                                                    	at android.view.View.updateDisplayListIfDirty(View.java:22712)
                                                                                                    	at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540)
                                                                                                    	at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513)
                                                                                                    	at android.view.View.updateDisplayListIfDirty(View.java:22712)
                                                                                                    	at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540)
                                                                                                    	at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513)
                                                                                                    	at android.view.View.updateDisplayListIfDirty(View.java:22712)
                                                                                                    	at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540)
                                                                                                    	at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513)
                                                                                                    	at android.view.View.updateDisplayListIfDirty(View.java:22712)
                                                                                                    	at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540)
                                                                                                    	at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513)
                                                                                                    	at android.view.View.updateDisplayListIfDirty(View.java:22712)
                                                                                                    	at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:694)
                                                                                                    	at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:700)
                                                                                                    	at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:798)
                                                                                                    	at android.view.ViewRootImpl.draw(ViewRootImpl.java:4939)
                                                                                                    	at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:4643)
                                                                                                    	at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3822)
                                                                                                    	at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2465)
                                                                                                    	at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9305)
2024-05-20 15:56:17.422 23934-23934 AndroidRuntime          com.fabrictestexample                E  	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1339)
                                                                                                    	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1348)
                                                                                                    	at android.view.Choreographer.doCallbacks(Choreographer.java:952)
                                                                                                    	at android.view.Choreographer.doFrame(Choreographer.java:882)
                                                                                                    	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1322)
                                                                                                    	at android.os.Handler.handleCallback(Handler.java:958)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:205)
                                                                                                    	at android.os.Looper.loop(Looper.java:294)
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:8177)
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method)
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

tboba avatar May 20 '24 13:05 tboba

I used a slightly modified Test556 for testing my PR based on your changes. There is an error on android when navigating back with a custom headerTitle and headerRight: Screenshot 2024-07-16 at 14 48 58

Works fine when there's just one custom header element, works fine on iOS.

Repro code
import * as React from 'react';
import { Button, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator
        screenOptions={{
          headerTitle: () => <Text>Simple Native Stack</Text>,
          headerRight: () => <Text>Right</Text>,
        }}>
        <Stack.Screen name="First" component={First} />
        <Stack.Screen name="Second" component={Second} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

function First({ navigation }) {
  return (
    <Button
      title="Tap me for second screen"
      onPress={() => navigation.navigate('Second')}
    />
  );
}

function Second({ navigation }) {
  return (
    <Button
      title="Tap me for second screen"
      onPress={() => navigation.popTo('First')}
    />
  );
}

alduzy avatar Jul 16 '24 12:07 alduzy

I can confirm the latest change fixes the issue I came upon 🎉

alduzy avatar Jul 19 '24 15:07 alduzy