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

Android crashes nondeterministically when restoring from background #17

Closed
ukasiu opened this issue Sep 25, 2018 · 72 comments · Fixed by AtB-AS/mittatb-app#248 or artsy/eigen#5062

Comments

@ukasiu
Copy link

ukasiu commented Sep 25, 2018

Hi,

at least in release builds I'm getting crashes when restoring app from background, but not always. I replaced ReactActivity with ReactFragmentActivity.

react-native: 0.57.0

Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com._redacted_.app/com._redacted_.app.MainActivity}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.swmansion.rnscreens.Screen$ScreenFragment: calling Fragment constructor caused an exception
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2747)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2808)
       at android.app.ActivityThread.-wrap12(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1541)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:165)
       at android.app.ActivityThread.main(ActivityThread.java:6365)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:883)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
       at android.support.v4.app.Fragment.instantiate(Fragment.java:386)
       at android.support.v4.app.FragmentContainer.instantiate(FragmentContainer.java:33)
       at android.support.v4.app.FragmentState.instantiate(FragmentState.java:79)
       at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:3080)
       at android.support.v4.app.FragmentController.restoreAllState(FragmentController.java:152)
       at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:330)
       at com.facebook.react.ReactFragmentActivity.onCreate(ReactFragmentActivity.java:54)
       at com._redacted_.app.MainActivity.onCreate(MainActivity.java:19)
       at android.app.Activity.performCreate(Activity.java:6852)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2700)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2808)
       at android.app.ActivityThread.-wrap12(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1541)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:165)
       at android.app.ActivityThread.main(ActivityThread.java:6365)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:883)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
Caused by java.lang.reflect.InvocationTargetException
       at java.lang.reflect.Constructor.newInstance0(Constructor.java)
       at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
       at android.support.v4.app.Fragment.instantiate(Fragment.java:364)
       at android.support.v4.app.FragmentContainer.instantiate(FragmentContainer.java:33)
       at android.support.v4.app.FragmentState.instantiate(FragmentState.java:79)
       at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:3080)
       at android.support.v4.app.FragmentController.restoreAllState(FragmentController.java:152)
       at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:330)
       at com.facebook.react.ReactFragmentActivity.onCreate(ReactFragmentActivity.java:54)
       at com._redacted_.app.MainActivity.onCreate(MainActivity.java:19)
       at android.app.Activity.performCreate(Activity.java:6852)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2700)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2808)
       at android.app.ActivityThread.-wrap12(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1541)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:165)
       at android.app.ActivityThread.main(ActivityThread.java:6365)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:883)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
Caused by java.lang.IllegalStateException: Screen fragments should never be restored
       at com.swmansion.rnscreens.Screen$ScreenFragment.<init>(Screen.java:19)
       at java.lang.reflect.Constructor.newInstance0(Constructor.java)
       at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
       at android.support.v4.app.Fragment.instantiate(Fragment.java:364)
       at android.support.v4.app.FragmentContainer.instantiate(FragmentContainer.java:33)
       at android.support.v4.app.FragmentState.instantiate(FragmentState.java:79)
       at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:3080)
       at android.support.v4.app.FragmentController.restoreAllState(FragmentController.java:152)
       at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:330)
       at com.facebook.react.ReactFragmentActivity.onCreate(ReactFragmentActivity.java:54)
       at com._redacted_.app.MainActivity.onCreate(MainActivity.java:19)
       at android.app.Activity.performCreate(Activity.java:6852)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2700)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2808)
       at android.app.ActivityThread.-wrap12(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1541)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:165)
       at android.app.ActivityThread.main(ActivityThread.java:6365)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:883)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
Fatal Exception: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
       at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:2053)
       at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:2079)
       at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:678)
       at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:632)
       at com.swmansion.rnscreens.ScreenContainer.tryCommitTransaction(ScreenContainer.java:99)
       at com.swmansion.rnscreens.ScreenContainer.updateIfNeeded(ScreenContainer.java:173)
       at com.swmansion.rnscreens.ScreenContainer.access$000(ScreenContainer.java:21)
       at com.swmansion.rnscreens.ScreenContainer$1.doFrame(ScreenContainer.java:34)
       at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:134)
       at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:105)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:964)
       at android.view.Choreographer.doCallbacks(Choreographer.java:778)
       at android.view.Choreographer.doFrame(Choreographer.java:710)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:952)
       at android.os.Handler.handleCallback(Handler.java:790)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:172)
       at android.app.ActivityThread.main(ActivityThread.java:6590)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
@kmagiera
Copy link
Member

😱

@kmagiera
Copy link
Member

kmagiera commented Sep 26, 2018

As a workaround for this issue I suggest adding the following code to the main activity class (the one that extends ReactFragmentActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(null);
}

@kmagiera
Copy link
Member

We should perhaps make it a default behavior for the main activity class in RN core as restoring instance state won't work in RN this way anyways

@hey99xx
Copy link

hey99xx commented Sep 26, 2018

Agreed. Generally speaking if you cannot save your JS memory (Redux stores, in-component state etc.), then saving only your view state could likely cause inconsistencies.

But then again in a single-activity-app, not saving the activity state means that your app is essentially restarting whenever OS kills your activity for any reason.

Does react-native-navigation attempt to deal with process death challenge, I don't know. Maybe it'd be better to let to the hosting navigation libraries deal with this. In practice they could keep saving each new screen props on into a bundle in the main activity, put this bundle into the one given in onSaveInstanceState and send the data back to as props on activity recreation through ReactRootView.startReactApplication(reactInstanceManager, moduleName, initialProps) method.

Btw my app doesn't have this problem as we have an architecture (not using this library, but I'd like to in the future) where each screen is an instance of an activity, and the props are sent through converting a ReadableMap into a Bundle and storing the Intent extras. This way we never lose the props at process death, and the props are usually sufficient to recreate the flow the user had left the app in. Not necessarily advocating for multiple activities but just explaining how we solved it.

@janicduplessis
Copy link
Contributor

janicduplessis commented Sep 27, 2018

I hit this issue too, maybe we should add the workaround in the installation instructions.

It is easy to reproduce by using the dev settings to kill background activities.

@kmagiera
Copy link
Member

Going to add that @janicduplessis

Thanks @hey99xx for your input. The thing is that RN app is not able to restore the app state properly. So even if we were able to bring back all the views from the previous state the app won't be able to pick that up and start from there. Now when system kills the app it starts all over. In fact Android restore mechanism isn't really reliable even outside RN apps, you can try enabling developer option "don't keep activities" for a day to see it does not work in most of the apps (even some parts of the gmail app). React-native-navigation does not deal with that either, in fact it does not rely either on activities nor fragments, just have their own containers based off of ViewGroup, so behaves exactly the same way as any other RN app with regard to that.

Having each screen launch an app using startReactApplication makes your app keep the activity stack. Note that this does not guarantee you that the state is going to be restored correctly. The reasons are the same as why with many Android native apps this mechanism isn't reliable. So for example you may have some redux state that has been changed on a screen down the stack. Then when system restores the app it will open the stack of activities and load proper screens into each of the activities but there are chances some of the content on these screens may rely on the redux state that is going to be cleared (unless persisted) when the app gets killed.

@hey99xx
Copy link

hey99xx commented Sep 27, 2018

I understand your reasonings and that's what I mentioned in my first paragraph too, saving only your view state is solving only half of the problem, and will cause inconsistencies as your Redux state will be entirely gone unless you find ways to persist it (I guess redux-persist could work here). I don't think we have a disagreement here.

Then when system restores the app it will open the stack of activities and load proper screens into each of the activities but there are chances some of the content on these screens may rely on the redux state that is going to be cleared (unless persisted) when the app gets killed.

This is also true, but from my experience props tend to be sufficient, and saving further state in the activity is not super necessary. In fact this approach is a bit similar to WebView.saveState(Bundle) method as it only saves the back/forward list (something like history) and not bother with serializing the DOM or JS state itself. Of course you need to take a bit of care while passing props to make sure you can regenerate a page through props alone and do not entirely rely on local Redux stores.

We have this architecture not necessarily because it's the best but because we have a hybrid app and we need to be able to have activity stacks where some are RN based and some are pure native, so we cannot use any traditional navigation libraries. Otherwise I already understand the downsides of our activity per screen solution.

As a solution to this GitHub issue I think super.onCreate(null); should be added to the README file and that should be enough. Nevermind you've already done it.

@kmagiera
Copy link
Member

Thanks @hey99xx I think we are on the same page with regard to that

@K-Leon
Copy link

K-Leon commented Dec 7, 2018

The workaround doesn't solve it for me - anyone found something else which could cause this?

@jgcmarins
Copy link

facing same crash here

@joaodematejr
Copy link

+1

@kmagiera
Copy link
Member

Thanks @K-Leon @jgcmarins @joaodematejr for leaving your notes. I'd appreciate it very much if you could find a minute to include a stacktrace from the crash you are experiencing and also version of the library + RN version your app uses.

@jgcmarins
Copy link

@kmagiera sure!
I share same RN version as @ukasiu, 0.57.0
And I've got same stacktrace.
react-native-screens version: 1.0.0-alpha.21

@K-Leon
Copy link

K-Leon commented Feb 22, 2019

    at com.swmansion.rnscreens.ScreenContainer.<init>(ScreenContainer.java:44)
    at com.swmansion.rnscreens.ScreenContainerViewManager.createViewInstance(ScreenContainerViewManager.java:21)
    at com.swmansion.rnscreens.ScreenContainerViewManager.createViewInstance(ScreenContainerViewManager.java:9)
    at com.facebook.react.uimanager.ViewManager.createView(ViewManager.java:42)
    at com.facebook.react.uimanager.NativeViewHierarchyManager.createView(NativeViewHierarchyManager.java:260)
    at com.facebook.react.uimanager.UIViewOperationQueue$CreateViewOperation.execute(UIViewOperationQueue.java:200)
    at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:888)
    at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:1001)
    at com.facebook.react.uimanager.UIViewOperationQueue.access$2400(UIViewOperationQueue.java:46)
    at com.facebook.react.uimanager.UIViewOperationQueue$2.runGuarded(UIViewOperationQueue.java:959)
    at com.facebook.react.bridge.GuardedRunnable.run(GuardedRunnable.java:24)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5254)
    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:902)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:697)```

@kmagiera
Copy link
Member

@jgcmarins can you please try it with screens@1.0.0-alpha.22 then?

@K-Leon thanks for sending the stacktrace but it is missing the top of the trace (where the exception is specified) which is the most important part. Also if exception has a cause ("caused by" section) that would be an important information too

@jgcmarins
Copy link

jgcmarins commented Mar 13, 2019

@kmagiera version 1.0.0-alpha.22 did the trick.
Thanks \o/

I also updated to rn 0.59.

@nonotest
Copy link

Hello,

I am on rn 0.58.6 and 1.0.0-alpha.22 and just had a similar crash report

java.lang.RuntimeException: 
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2778)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2856)
  at android.app.ActivityThread.-wrap11 (Unknown Source)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1589)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:6501)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:438)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:807)
Caused by: android.support.v4.app.Fragment$InstantiationException: 
  at android.support.v4.app.Fragment.instantiate (Fragment.java:465)
  at android.support.v4.app.FragmentContainer.instantiate (FragmentContainer.java:50)
  at android.support.v4.app.FragmentState.instantiate (FragmentState.java:80)
  at android.support.v4.app.FragmentManagerImpl.restoreAllState (FragmentManager.java:3109)
  at android.support.v4.app.FragmentController.restoreAllState (FragmentController.java:158)
  at android.support.v4.app.FragmentActivity.onCreate (FragmentActivity.java:344)
  at com.facebook.react.ReactFragmentActivity.onCreate (ReactFragmentActivity.java:54)
  at com.stocksinplay.sip.MainActivity.onCreate (MainActivity.java:27)
  at android.app.Activity.performCreate (Activity.java:7026)
  at android.app.Activity.performCreate (Activity.java:7017)
  at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1215)
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2731)
Caused by: java.lang.reflect.InvocationTargetException: 
  at java.lang.reflect.Constructor.newInstance0 (Native Method)
  at java.lang.reflect.Constructor.newInstance (Constructor.java:334)
  at android.support.v4.app.Fragment.instantiate (Fragment.java:443)
Caused by: java.lang.IllegalStateException: 
  at com.swmansion.rnscreens.Screen$ScreenFragment.<init> (Screen.java:23)

ill try to upgrade to 59 later
note its the first time i see this in weeks

@erandagan
Copy link

erandagan commented Mar 17, 2019

Here's another occurrence with the latest version of screens (alpha 22), with the full stacktrace in a release build.

Caused by: android.support.v4.app.Fragment$InstantiationException Unable to instantiate fragment com.swmansion.rnscreens.b$a: calling Fragment constructor caused an exception 
    Fragment.java:386 android.support.v4.app.Fragment.instantiate
    FragmentContainer.java:33 android.support.v4.app.FragmentContainer.instantiate
    FragmentState:79 android.support.v4.app.FragmentState.instantiate
    FragmentManager.java:3080 android.support.v4.app.FragmentManagerImpl.restoreAllState
    FragmentController:152 android.support.v4.app.FragmentController.restoreAllState
    FragmentActivity.java:330 android.support.v4.app.FragmentActivity.onCreate
    ReactFragmentActivity.java:54 com.facebook.react.ReactFragmentActivity.onCreate
    MainActivity.java:15 com.[APPNAME].android.MainActivity.onCreate
    Activity.java:6910 android.app.Activity.performCreate
    Instrumentation.java:1123 android.app.Instrumentation.callActivityOnCreate
    ActivityThread.java:2746 android.app.ActivityThread.performLaunchActivity
    ActivityThread.java:2864 android.app.ActivityThread.handleLaunchActivity
    ActivityThread.java:-1 android.app.ActivityThread.-wrap12
    ActivityThread.java:1567 android.app.ActivityThread$H.handleMessage
    Handler.java:102 android.os.Handler.dispatchMessage
    Looper.java:156 android.os.Looper.loop
    ActivityThread.java:6524 android.app.ActivityThread.main
    Method.java:-2 java.lang.reflect.Method.invoke
    ZygoteInit.java:941 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
    ZygoteInit.java:831 com.android.internal.os.ZygoteInit.main


Caused by: java.lang.reflect.InvocationTargetException
    Constructor.java:-2 java.lang.reflect.Constructor.newInstance0
    Constructor.java:430 java.lang.reflect.Constructor.newInstance
    Fragment.java:364 android.support.v4.app.Fragment.instantiate
    FragmentContainer.java:33 android.support.v4.app.FragmentContainer.instantiate
    FragmentState:79 android.support.v4.app.FragmentState.instantiate
    FragmentManager.java:3080 android.support.v4.app.FragmentManagerImpl.restoreAllState
    FragmentController:152 android.support.v4.app.FragmentController.restoreAllState
    FragmentActivity.java:330 android.support.v4.app.FragmentActivity.onCreate
    ReactFragmentActivity.java:54 com.facebook.react.ReactFragmentActivity.onCreate
    MainActivity.java:15 com.[APPNAME].android.MainActivity.onCreate
    Activity.java:6910 android.app.Activity.performCreate
    Instrumentation.java:1123 android.app.Instrumentation.callActivityOnCreate
    ActivityThread.java:2746 android.app.ActivityThread.performLaunchActivity
    ActivityThread.java:2864 android.app.ActivityThread.handleLaunchActivity
    ActivityThread.java:-1 android.app.ActivityThread.-wrap12
    ActivityThread.java:1567 android.app.ActivityThread$H.handleMessage
    Handler.java:102 android.os.Handler.dispatchMessage
    Looper.java:156 android.os.Looper.loop
    ActivityThread.java:6524 android.app.ActivityThread.main
    Method.java:-2 java.lang.reflect.Method.invoke
    ZygoteInit.java:941 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
    ZygoteInit.java:831 com.android.internal.os.ZygoteInit.main


Caused by: java.lang.IllegalStateException Screen fragments should never be restored 
    Screen.java:23 com.swmansion.rnscreens.Screen$ScreenFragment.<init>
    Constructor.java:-2 java.lang.reflect.Constructor.newInstance0
    Constructor.java:430 java.lang.reflect.Constructor.newInstance
    Fragment.java:364 android.support.v4.app.Fragment.instantiate
    FragmentContainer.java:33 android.support.v4.app.FragmentContainer.instantiate
    FragmentState:79 android.support.v4.app.FragmentState.instantiate
    FragmentManager.java:3080 android.support.v4.app.FragmentManagerImpl.restoreAllState
    FragmentController:152 android.support.v4.app.FragmentController.restoreAllState
    FragmentActivity.java:330 android.support.v4.app.FragmentActivity.onCreate
    ReactFragmentActivity.java:54 com.facebook.react.ReactFragmentActivity.onCreate
    MainActivity.java:15 com.[APPNAME].android.MainActivity.onCreate
    Activity.java:6910 android.app.Activity.performCreate
    Instrumentation.java:1123 android.app.Instrumentation.callActivityOnCreate
    ActivityThread.java:2746 android.app.ActivityThread.performLaunchActivity
    ActivityThread.java:2864 android.app.ActivityThread.handleLaunchActivity
    ActivityThread.java:-1 android.app.ActivityThread.-wrap12
    ActivityThread.java:1567 android.app.ActivityThread$H.handleMessage
    Handler.java:102 android.os.Handler.dispatchMessage
    Looper.java:156 android.os.Looper.loop
    ActivityThread.java:6524 android.app.ActivityThread.main
    Method.java:-2 java.lang.reflect.Method.invoke
    ZygoteInit.java:941 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
    ZygoteInit.java:831 com.android.internal.os.ZygoteInit.main

The exception root is in this line.

@jgcmarins
Copy link

I am now facing a crash after closing the app and opening it again.
The stack trace is like this one: #54

@zth
Copy link

zth commented Aug 19, 2019

@jgcmarins did this ever get resolved for you?

@jgcmarins
Copy link

Sorry, can't confirm because I am not working on that app anymore. Maybe @sibelius can help with this answer.

@sibelius
Copy link

fixed for us

@mohamadnavabi
Copy link

This bug was fixed for me. When I downgraded to react-native-screens@^2.15.0

@SanderNiesten
Copy link

Question: Instead of forcibly passing null to the constructor, what is the downside of selectively removing the fragment info from savedInstanceState ?

Not really sure about the correct keys to use (for portability) though. I found those android:support:fragments and android:fragments when logging the bundle content.

    protected void onCreate(Bundle savedInstanceState) {
		if (savedInstanceState != null) {
			savedInstanceState.remove("android:support:fragments");
			savedInstanceState.remove("android:fragments");
		}
               super.onCreate(savedInstanceState);
    }

This does not result in a crash with both Keep Activities on or off.

Tested it with multiple devices as well, seems like a better approach and setup for the readme as suggested.

@mikehardy
Copy link
Contributor

So hit that edit button and make a PR :-)

@marqroldan
Copy link

marqroldan commented Jul 30, 2021

Question: Instead of forcibly passing null to the constructor, what is the downside of selectively removing the fragment info from savedInstanceState ?
Not really sure about the correct keys to use (for portability) though. I found those android:support:fragments and android:fragments when logging the bundle content.

    protected void onCreate(Bundle savedInstanceState) {
		if (savedInstanceState != null) {
			savedInstanceState.remove("android:support:fragments");
			savedInstanceState.remove("android:fragments");
		}
               super.onCreate(savedInstanceState);
    }

This does not result in a crash with both Keep Activities on or off.

Tested it with multiple devices as well, seems like a better approach and setup for the readme as suggested.

I'm using this code but unfortunately there are still a few people (100 in 7 days) that crashes during onPause, we're also using codepush so it could be another factor

Or maybe this error of mine is unrelated D;

Unable to pause activity | java.lang.IllegalArgumentException: No view found for id 0x157 (unknown) for fragment ScreenFragment{c412ddd} (40172dfe-f9be-44f2-9bdc-2a8876e62661) id=0x157}

No view found for id 0x157 (unknown) for fragment ScreenFragment{c412ddd} (40172dfe-f9be-44f2-9bdc-2a8876e62661) id=0x157}

@WoLewicki
Copy link
Member

@marqroldan I believe it is this one: #463, and there is a solution provided, but it needs to be tested thoroughly: #463 (comment)

@imattaullah
Copy link

Add this on activity

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.clear();
    }

@thientnc-galaxyone
Copy link

Add this on activity

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.clear();
    }

This code makes NullPointerException

@mikehardy
Copy link
Contributor

if (outState != null) { outState.clear(); } - bundle is null onCreate but onResume of activity it has values and that's your crash

@hippiejuice
Copy link

hippiejuice commented Sep 9, 2021

@WoLewicki Has there been a fix or support added for restoring screen fragments? What are the repro steps? I'm on react-native 0.63.3 and react-native-screens 3.4.0, and we are starting to see this crash in our app in production. We haven't added the first recommended fix of passing null into onCreate since we want to preserve state if the app is relaunched from the background - but I also haven't been able to repro this locally. Any help here would be appreciated to better understand what's going on and what's the current state of things.

@lkw1830
Copy link

lkw1830 commented Sep 13, 2021

as comment suggested pass null to onCreate, however, on foldable phone the whole application will restart whenever we split into multi-window. Any other ways could prevent such issue? Thanks.

@pke
Copy link

pke commented Sep 21, 2021

@mikehardy is this the better fix (with the null guard)?

@mikehardy
Copy link
Contributor

Probably yes, but as with anything, test it in use

@mikehardy
Copy link
Contributor

as comment suggested pass null to onCreate, however, on foldable phone the whole application will restart whenever we split into multi-window. Any other ways could prevent such issue? Thanks.

Any screen rotation, permission change, language change, theme change etc also represent what android calls configuration changes and they all restart the app. Save nav state and dehydrate rehydrate in app

@pke
Copy link

pke commented Sep 21, 2021

Probably yes, but as with anything, test it in use

Would love to but so far this issue only happens with deployed versions out there. I was never able to reproduce it. Any idea how to force it?

@kacperkapusciak
Copy link
Member

@lkw1830 you can fix that issue by setting up screenLayout & smallestScreenSize flags in android:configChanges option in your AndroidManifest.xml file.

So eg. here in our example app
https://github.com/software-mansion/react-native-screens/blob/master/Example/android/app/src/main/AndroidManifest.xml#L19

set it as

android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode|screenLayout|smallestScreenSize"

When I was testing this setting up screenLayout flag was sufficient but documentation recommends both of these flags.

Source: https://developer.android.com/guide/topics/manifest/activity-element#config

@mikehardy
Copy link
Contributor

@kacperkapusciak that's a neat trick and a good strategy! I do similar, but I still have the Bundle-clearing workaround as well, as what I fear happens (and what appears to have happened with at least 'smallestScreenSize' is that new config items are added to the list of things that can cause an Activity restart without me realizing it, resulting in a new vector for restarts and new crashes until I notice them. Setting the list to the current known config changes means in general it won't restart but the Bundle-clearing means it won't crash no matter what.

A question for you though: do you correctly apply new locale configurations or new screen rotation configurations in the example app? Just curious if you've plumbed that through some other way (perhaps there are core react-native events I need to educate myself on...)

@Daha62
Copy link

Daha62 commented Oct 18, 2021

same issue on react-natvie-screens 2.15.1 everything works correctly but on 3.7.0 - app started to crash

@anija
Copy link

anija commented Dec 6, 2021

Also on 3.9.0 the app crash

@pke
Copy link

pke commented Dec 6, 2021

@anija did you use one of the proposed fixes from this issue here? We did apply the fix suggested in the readme and no longer have android crashes out there. None (related to this bug).

@kacperkapusciak
Copy link
Member

For anyone coming here from Google:

Fix for the crash 👉 #17 (comment)

The problem is explained both in the installation steps in react-native-screens README: Installation for Android

and

in the react-navigation docs: Installing dependencies into a bare React Native project

@software-mansion software-mansion locked as resolved and limited conversation to collaborators Dec 9, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet