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] needs good solution to handling configuration change, e.g. orientation change #3219

Closed
marty-wang opened this Issue Oct 4, 2015 · 19 comments

Comments

Projects
None yet
@marty-wang
Copy link

marty-wang commented Oct 4, 2015

It is critical and tedious and error-prone to save/restore state in Android, given that the configuration change can happen very often, therefore it requires developers to have good discipline and great efforts to make it right. It is already hard to do it in Android, it is even harder to do it in React Native, IMO, because it is common (maybe recommended?) to have one activity in React Native Android app and the root view contains the whole app. What are developers now supposed to do hook onto the activity life cycle to save/restore state without errors? I check out FB's ad manager from google play store. The app itself disables the orientation change. Maybe it just so happens to work out for the ad manager, in terms of UX. but it is far from being enough for the community. The other app from third part in the play store does not disable orientation change and the app's state just gets lost whenever orientation changes. Any serious app cannot allow that.

Please come up with and recommend a good solution to us. I think it is a must to make React Native successful on Android, and to be a much better programming model than the one of Android.

@satya164

This comment has been minimized.

Copy link
Collaborator

satya164 commented Oct 4, 2015

There is a third party module https://github.com/walmartreact/react-native-orientation-listener

May be it can help?

@marty-wang

This comment has been minimized.

Copy link
Author

marty-wang commented Oct 6, 2015

I am not sure if the orientation listener will actually help, because, 1.) orientation change is one of those configuration change that can cause the activity to recreate. There are a few others. 2.) unless the event notifies JavaScript code before Android destroys the activity, so that JavaScript code has chance to save the current state, it would be useless.

The solution has to come from framework. I noticed that in the doc FB will add AppState API, just like AppStateIOS, as common API, which is presumably to be able to notify JavaScript code at right timing.

What I am hoping here is that once the AppState API is released, and of course if it works like the IOS counterpart, FB will provide some samples to showcase the pattern to handling state saving/restoring. We absolutely need have good guidelines of how to do it correctly, because as I said in my original post, it is very critical for any serious app, but very hard to get it right. (Just look at how long it takes Google to come up with Persist Fragment, which is sort of OK for the similar purpose)

@satya164

This comment has been minimized.

Copy link
Collaborator

satya164 commented Oct 6, 2015

@marty-wang

I am not sure if the orientation listener will actually help, because, 1.) orientation change is one of those configuration change that can cause the activity to recreate. There are a few others. 2.) unless the event notifies JavaScript code before Android destroys the activity, so that JavaScript code has chance to save the current state, it would be useless.

You can prevent it by adding android:configChanges="keyboard|keyboardHidden|orientation|screenSize" to your AndroidManifest.xml, like so,

...
<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
...

After this is done, the UI responds just fine to orientation change. If some part of your UI needs to change on dimension change, you can easily use the orientation listener to do that.

@marty-wang

This comment has been minimized.

Copy link
Author

marty-wang commented Oct 6, 2015

@satya164 Thanks for the tip. It will come in handy for now.

However, the intention of my post is not really to look for a workaround. I want to bring out the attention that React Native as a framework needs to offer a good pattern/guideline for app state management. Hopefully it will be on the top of the list at some point.

@satya164

This comment has been minimized.

Copy link
Collaborator

satya164 commented Oct 6, 2015

@marty-wang Yes, Do you have any suggestions on how it can be handled?

@morenoh149

This comment has been minimized.

Copy link
Contributor

morenoh149 commented Dec 30, 2015

I'm running into this as well. my UI loses state on android and rerenders on orientation change. What are the down sides to adding the configChanges line to the manifest file by default?

@morenoh149

This comment has been minimized.

Copy link
Contributor

morenoh149 commented Dec 30, 2015

Reading Handling runtime changes it seems RN should do something more intelligent with onConfigurationChanged(). This method is passed updated dimensions which would also fix #3264 #2111 #4934 #3820

@satya164

This comment has been minimized.

Copy link
Collaborator

satya164 commented Dec 30, 2015

@morenoh149 No downsides AFAIK. It's added by default in the template as of 6c11d18

@astuetz

This comment has been minimized.

Copy link
Contributor

astuetz commented Mar 25, 2016

Rather "old" issue but still totally relevant imo.
If you include React Native in an existing Android app (instead of just having one "React Native Activity"), simply using android:configChanges just isn't possible, as this would break other parts of the app.
Yesterday I had to explain to one of our PMs why the whole RN screen gets kicked and re-created once I rotate the device.
For example, this is how we include RN in our app:

  • We have one Base Activity which includes a Navigation Drawer
  • If you select an item of the Drawer, we simply show a different Fragment inside the Activity
  • The RN part is embedded into its own Fragment, which creates a new ReactRootView and calls startReactApplication etc.

So we would have to add the configChanges flags to the Activity, which breaks other Fragments inside this Activity then.
Another solution would be to just start a "React Native Activity" as soon as the RN drawer item is selected, but this is a no-go UX wise on our side.

Right now I'm trying out everything I can, maybe someone of you understands our problem and has a good idea on what to do?
Would be cool to find a solution where adding configChanges in the Manifest isn't necessary at all.

@satya164

This comment has been minimized.

Copy link
Collaborator

satya164 commented Mar 25, 2016

@astuetz Check the link @morenoh149 shared, it says the following,

To retain stateful objects in a fragment during a runtime configuration change:

  1. Extend the Fragment class and declare references to your stateful objects.
  2. Call setRetainInstance(boolean) when the fragment is created.
@astuetz

This comment has been minimized.

Copy link
Contributor

astuetz commented Mar 25, 2016

@satya164 The Fragment itself might not be destroyed on an orientation change, but the ReactRootView (or basically everything associated with the Activity Context) still has to be recreated afterwards, as otherwise it would leak the previous, old Activity instance.
Or am I missing something here?

@astuetz

This comment has been minimized.

Copy link
Contributor

astuetz commented Mar 29, 2016

Pinging @mkonicek: Do you know what the Facebook team is doing here internally? Are they just setting android:configChanges on all the Activities as well? Maybe we can bring this issue to Product Pains, as relying on these flags feels more like a workaround rather than a solution.

@chriswiesner

This comment has been minimized.

Copy link

chriswiesner commented Apr 4, 2016

+1

@mkonicek

This comment has been minimized.

Copy link
Contributor

mkonicek commented Apr 20, 2016

@astuetz We don't handle screen rotation in any of our apps yet.

Sorry I missed this issue, I get many GitHub notifications. Feel free to also post discussions like this on StackOverflow or the React Native Community fb group. Chances are people from the community who have context on the issue will help.

The sample app for the Facebook React Native SDK does use android:configChanges, see https://github.com/facebook/react-native-fbsdk/blob/master/Sample/HelloFacebook/android/app/src/main/AndroidManifest.xml#L24

the ReactRootView (or basically everything associated with the Activity Context) still has to be recreated afterwards

I would assume this is the way it works, but check out the tip on setRetainInstance above. Maybe there's a way not to recreate the root view? I'm not too sure, posting in more places to get more people looking at this might help find someone who solved this before.

@astuetz

This comment has been minimized.

Copy link
Contributor

astuetz commented Apr 21, 2016

Thanks for the reply, @mkonicek!
I didn't know about the fb group, will post it there as well as on StackOverflow. Thought maybe you guys already might have had the problem and know what to do.
I think the problem can't be solved on the app-side, I planned to investigate some time to check how this could be handled in React Native.

@cmmouritsen

This comment has been minimized.

Copy link

cmmouritsen commented Jul 12, 2016

@astuetz Have you been able to discover any kind of resolution for this? I'm also running into an issue that can't be resolved by simply setting the android:configChanges in the manifest file.

@astuetz

This comment has been minimized.

Copy link
Contributor

astuetz commented Jul 15, 2016

@cmmouritsen unfortunately we haven't had time yet to investigate this i detail. Right now we're just trying to live with the problem :(

@Larney11

This comment has been minimized.

@mkonicek mkonicek added the Icebox label Oct 27, 2016

@mkonicek

This comment has been minimized.

Copy link
Contributor

mkonicek commented Oct 27, 2016

Hi there! This issue is being closed because it has been inactive for a while.

But don't worry, it will live on with ProductPains! Check out its new home: https://productpains.com/post/react-native/android-needs-good-solution-to-handling-configuration-change-eg-orientation-change

ProductPains helps the community prioritize the most important issues thanks to its voting feature.
It is easy to use - just login with GitHub. GitHub issues have voting too, nevertheless
Product Pains has been very useful in highlighting the top bugs and feature requests:
https://productpains.com/product/react-native?tab=top

Also, if this issue is a bug, please consider sending a pull request with a fix.
We're a small team and rely on the community for bug fixes of issues that don't affect fb apps.

@mkonicek mkonicek closed this Oct 27, 2016

@facebook facebook locked as resolved and limited conversation to collaborators Jul 21, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.