Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upInstance state not saved when app is killed by OS #6827
Comments
eseidelGoogle
added
engine
framework
▣ platform-android
labels
Nov 12, 2016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
#3427 is also likely related. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
LouisCAD
Nov 12, 2016
@eseidelGoogle That's right. In which format could the flutter Activity state be saved, if it can be at all as of the current version?
LouisCAD
commented
Nov 12, 2016
|
@eseidelGoogle That's right. In which format could the flutter Activity state be saved, if it can be at all as of the current version? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Hixie
Nov 12, 2016
Contributor
Right now we don't do anything to save anything.
The framework itself has very little state worth saving -- it's all animation and stuff like that -- so it may be that we always leave this up to the app to do. We should probably expose it at the Dart level though. (Right now it's only exposed at the Java level.)
|
Right now we don't do anything to save anything. The framework itself has very little state worth saving -- it's all animation and stuff like that -- so it may be that we always leave this up to the app to do. We should probably expose it at the Dart level though. (Right now it's only exposed at the Java level.) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
LouisCAD
Nov 12, 2016
@Hixie On Android, all framework Views have their state automatically saved and restored by the system, which only requires the developer to save manually the non UI part of the instance state. Shouldn't flutter work the same way for all UI widgets to prevent developers from having to write all the boilerplate each time to save where the user was, the scroll position, the enabled state of some button, the state of the previous screen and so on…?
LouisCAD
commented
Nov 12, 2016
|
@Hixie On Android, all framework Views have their state automatically saved and restored by the system, which only requires the developer to save manually the non UI part of the instance state. Shouldn't flutter work the same way for all UI widgets to prevent developers from having to write all the boilerplate each time to save where the user was, the scroll position, the enabled state of some button, the state of the previous screen and so on…? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Hixie
Nov 14, 2016
Contributor
In Flutter, there's very little framework state to save. For example, the enabled state of a button is not state, it's input provided by the application. The current route history is stored in the framework, but not stored in a state that the framework can rebuild (since it's all instances of objects provided by the application code). The scroll position is about the only thing we could actually store (and we do save that in a store currently, just not one that survives the app).
But in any case we should definitely do better than today.
|
In Flutter, there's very little framework state to save. For example, the enabled state of a button is not state, it's input provided by the application. The current route history is stored in the framework, but not stored in a state that the framework can rebuild (since it's all instances of objects provided by the application code). The scroll position is about the only thing we could actually store (and we do save that in a store currently, just not one that survives the app). But in any case we should definitely do better than today. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
LouisCAD
Nov 25, 2016
As an experienced Android Developer, I'd like to take part to the conversation with iOS developers too when it'll be discussed so flutter can be the perfect framework to build iOS and Android apps.
I think the persistence ability of the framework may be important to save data, preferences, cache data and states in the most developer friendly possible way.
LouisCAD
commented
Nov 25, 2016
|
As an experienced Android Developer, I'd like to take part to the conversation with iOS developers too when it'll be discussed so flutter can be the perfect framework to build iOS and Android apps. |
eseidelGoogle
referenced this issue
Nov 28, 2016
Closed
If I switch apps while typing text, the text is lost #7033
Hixie
added this to the
4: Make shippers happy milestone
Feb 27, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Takhion
Sep 24, 2017
Whoa I didn't realise this was the case? This is actually critical, and it's worth mentioning that on devices with less memory the process could be killed quite easily!
What about saving the PageStore (or related) as a byte stream through serialization.dart in onSaveInstanceState?
Takhion
commented
Sep 24, 2017
•
|
Whoa I didn't realise this was the case? This is actually critical, and it's worth mentioning that on devices with less memory the process could be killed quite easily! What about saving the |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
LouisCAD
Sep 27, 2017
@Takhion Could you link "PageStore" you're mentioning? I'm interested in trying to workaround this issue since it seems it won't be fixed any soon (31st december of 2029 is a liiittle far IMHO)
LouisCAD
commented
Sep 27, 2017
|
@Takhion Could you link "PageStore" you're mentioning? I'm interested in trying to workaround this issue since it seems it won't be fixed any soon (31st december of 2029 is a liiittle far IMHO) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Takhion
Sep 27, 2017
@LouisCAD sure it's here: https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/widgets/page_storage.dart
I think you'll need to save more than that though: at least the current route(s) and maybe some state?
What do you think @Hixie?
Takhion
commented
Sep 27, 2017
|
@LouisCAD sure it's here: https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/widgets/page_storage.dart I think you'll need to save more than that though: at least the current route(s) and maybe some state? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Hixie
Sep 29, 2017
Contributor
We don't currently do anything to make this easy. We haven't studied this problem in detail yet. For now I recommend storing the information you want to persist manually, and applying it afresh when the app is restored.
|
We don't currently do anything to make this easy. We haven't studied this problem in detail yet. For now I recommend storing the information you want to persist manually, and applying it afresh when the app is restored. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
sethladd
Oct 7, 2017
Contributor
Do we expose the necessary lifecycle events ("you're about to be killed!", "congrats, you're now restored") into Dart code, so developers can handle persisting state? That seems like the sufficient capabilities to unlock devs to explore solutions. Thoughts?
|
Do we expose the necessary lifecycle events ("you're about to be killed!", "congrats, you're now restored") into Dart code, so developers can handle persisting state? That seems like the sufficient capabilities to unlock devs to explore solutions. Thoughts? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
LouisCAD
Oct 7, 2017
@sethladd Just exposing it to developers is not enough IMHO. Flutter needs to save UI state too, without developers having to do it manually repeatedly for each app with dirty and hardly maintainable verbose boilerplate code.
LouisCAD
commented
Oct 7, 2017
|
@sethladd Just exposing it to developers is not enough IMHO. Flutter needs to save UI state too, without developers having to do it manually repeatedly for each app with dirty and hardly maintainable verbose boilerplate code. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
sethladd
Oct 7, 2017
Contributor
@LouisCAD thanks for the feedback. I'm thinking in steps... what's step one? Do we have the lifecycle events exposed yet?
|
@LouisCAD thanks for the feedback. I'm thinking in steps... what's step one? Do we have the lifecycle events exposed yet? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Takhion
commented
Oct 7, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
mit-mit
Oct 9, 2017
Member
@Hixie you mentioned over in #3427 that we do have hooks for lifecycle. Did you mean https://docs.flutter.io/flutter/widgets/WidgetsBindingObserver-class.html ?
|
@Hixie you mentioned over in #3427 that we do have hooks for lifecycle. Did you mean https://docs.flutter.io/flutter/widgets/WidgetsBindingObserver-class.html ? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
DanielNovak
Oct 10, 2017
Is Flutter using multiple Activities by default? (e.g. if you go to a new screen).
Process death is fairly common, the user hits the Home button and launches some other memory/CPU intensive application and your application will be killed in the background (or your application has been in the background for too long). It's an integral part of Android OS - every screen (Activity) should be able to persist and restore its' state and the process can be killed at any time after onStop().
Android will recreate the backstack of Activities if the user returns to a killed app, the top Activity is created first and then activities in the backstack are recreated on-demand if you go back in the backstack history. This can be a bigger issue in case Flutter is using multiple Activities (not sure if it does).
This means that if you don't have state saving implemented then the system will recreate the Activities but everything else is lost (process was killed), thus leading to inconsistency and crashes.
I wrote an article about process death on Android https://medium.com/inloop/android-process-kill-and-the-big-implications-for-your-app-1ecbed4921cb
DanielNovak
commented
Oct 10, 2017
•
|
Is Flutter using multiple Activities by default? (e.g. if you go to a new screen). Process death is fairly common, the user hits the Home button and launches some other memory/CPU intensive application and your application will be killed in the background (or your application has been in the background for too long). It's an integral part of Android OS - every screen (Activity) should be able to persist and restore its' state and the process can be killed at any time after onStop(). Android will recreate the backstack of Activities if the user returns to a killed app, the top Activity is created first and then activities in the backstack are recreated on-demand if you go back in the backstack history. This can be a bigger issue in case Flutter is using multiple Activities (not sure if it does). This means that if you don't have state saving implemented then the system will recreate the Activities but everything else is lost (process was killed), thus leading to inconsistency and crashes. I wrote an article about process death on Android https://medium.com/inloop/android-process-kill-and-the-big-implications-for-your-app-1ecbed4921cb |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
DanielNovak
Oct 10, 2017
Also there is no (clean) way to prevent Android from killing your application once it's past the onStop() state (after clicking Home or if the app is just not the current foreground app). So somehow you have to deal with it. Default Android widgets are saving their state (e.g. entered text in EditText) automatically into the Bundle instance. Your Activity will notify you that it's necessary to store your state by calling onSaveInstanceState(Bundle). So maybe Flutter should be able to forward this onSaveInstanceState callback from the Activity to your "screens". You will get the Bundle with the saved state back in the onCreate(Bundle savedInstanceState) or onRestoreInstanceState(Bundle savedInstanceState) lifecycle callback in your activity.
So to recap - Flutter could maybe forward the onSaveInstanceState() and onRestoreInstanceState() callbacks to the developer. Ideally you would also wrap the Android Bundle object into something that can be also used in Flutter. The next step would be that all Flutter widgets inside the screen would be also notified about these callbacks and use them to persist their current state.
The Android OS will then take the Bundle and actually persist it on disk so that it's not lost in case the process is killed and can be deserialized again.
Good luck with that :-). Please take care and don't introduce too much of this Android state / lifecycle hell to Flutter.
I am not sure how that works on iOS - but I think there is something similar but it's not "necessary" to use it (?).
DanielNovak
commented
Oct 10, 2017
•
|
Also there is no (clean) way to prevent Android from killing your application once it's past the onStop() state (after clicking Home or if the app is just not the current foreground app). So somehow you have to deal with it. Default Android widgets are saving their state (e.g. entered text in EditText) automatically into the Bundle instance. Your Activity will notify you that it's necessary to store your state by calling onSaveInstanceState(Bundle). So maybe Flutter should be able to forward this onSaveInstanceState callback from the Activity to your "screens". You will get the Bundle with the saved state back in the onCreate(Bundle savedInstanceState) or onRestoreInstanceState(Bundle savedInstanceState) lifecycle callback in your activity. So to recap - Flutter could maybe forward the onSaveInstanceState() and onRestoreInstanceState() callbacks to the developer. Ideally you would also wrap the Android Bundle object into something that can be also used in Flutter. The next step would be that all Flutter widgets inside the screen would be also notified about these callbacks and use them to persist their current state. Good luck with that :-). Please take care and don't introduce too much of this Android state / lifecycle hell to Flutter. I am not sure how that works on iOS - but I think there is something similar but it's not "necessary" to use it (?). |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
zoechi
Oct 10, 2017
Contributor
A lifecycle callback would be fine for me. I would just store/load the serialized redux state.
|
A lifecycle callback would be fine for me. I would just store/load the serialized redux state. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
sethladd
Oct 10, 2017
Contributor
Thanks for all the feedback! @Takhion also offered to help here. Perhaps an API design and a library is a good start? If that library works, we can look to integrate more formally. Also, the library will help identify what we need to do at the low-level engine (if anything). Basically: what's the concrete API proposal?
|
Thanks for all the feedback! @Takhion also offered to help here. Perhaps an API design and a library is a good start? If that library works, we can look to integrate more formally. Also, the library will help identify what we need to do at the low-level engine (if anything). Basically: what's the concrete API proposal? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Takhion
Oct 11, 2017
Is Flutter using multiple Activities by default? (e.g. if you go to a new screen)
@DanielNovak Flutter uses it's own "routing" system and by default it integrates with Android through a single View in a single Activity. You can have a hybrid Android/Flutter app and as such potentially multiple Activities and Flutter Views, but in that case you could easily save/restore instance state through Android directly.
I would just store/load the serialized redux state
@zoechi you probably don't want to do that because the saved instance state Bundle has to go through IPC with a hard limit of 1MB for your entire Android app state. Instance state, by definition, should only be the pieces of data that would allow you to recreate the same conditions of whatever in-progress activity the user is performing, so: text input, scroll position, current page, etc. Anything else should either be persisted on disk or derived from other state.
Takhion
commented
Oct 11, 2017
•
@DanielNovak Flutter uses it's own "routing" system and by default it integrates with Android through a single View in a single Activity. You can have a hybrid Android/Flutter app and as such potentially multiple Activities and Flutter Views, but in that case you could easily save/restore instance state through Android directly.
@zoechi you probably don't want to do that because the saved instance state Bundle has to go through IPC with a hard limit of 1MB for your entire Android app state. Instance state, by definition, should only be the pieces of data that would allow you to recreate the same conditions of whatever in-progress activity the user is performing, so: text input, scroll position, current page, etc. Anything else should either be persisted on disk or derived from other state. |
Hixie
referenced this issue
Oct 17, 2017
Closed
App state is lost when changing display density on Android #12588
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
raju-bitter
Oct 18, 2017
Contributor
Flutter exposes the Android onPause lifecycle event. The Android onDestroy() lifecycle event is not exposed. I guess the right approach would be to hook into the onPause() event for storing instance related state.
To be compatible with Android's onSaveInstanceState() and onRestoreInstanceState(), maybe it makes sense to add similar methods to Flutter widgets.
@sethladd @LouisCAD Did anyone create a design proposal?
|
Flutter exposes the Android onPause lifecycle event. The Android onDestroy() lifecycle event is not exposed. I guess the right approach would be to hook into the onPause() event for storing instance related state. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
DanielNovak
Oct 18, 2017
@raju-bitter onPause() is not optimal, it's better to hook into onSaveInstanceState(). Here is the javadoc from onSaveInstanceState which mentions that onPause() is called more regularly than onSaveInstanceState (you would be triggering state saving more often than necessary or when it's not necessary at all):
Do not confuse this method with activity lifecycle callbacks such as onPause(), which is always called when an activity is being placed in the background or on its way to destruction, or onStop() which is called before destruction. One example of when onPause() and onStop() is called and not this method is when a user navigates back from activity B to activity A: there is no need to call onSaveInstanceState(Bundle) on B because that particular instance will never be restored, so the system avoids calling it. An example when onPause() is called and not onSaveInstanceState(Bundle) is when activity B is launched in front of activity A: the system may avoid calling onSaveInstanceState(Bundle) on activity A if it isn't killed during the lifetime of B since the state of the user interface of A will stay intact.
DanielNovak
commented
Oct 18, 2017
|
@raju-bitter onPause() is not optimal, it's better to hook into onSaveInstanceState(). Here is the javadoc from onSaveInstanceState which mentions that onPause() is called more regularly than onSaveInstanceState (you would be triggering state saving more often than necessary or when it's not necessary at all):
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
zoechi
Oct 18, 2017
Contributor
instance state Bundle has to go through IPC with a hard limit of 1MB for your entire Android app state
That's not my issue.
I just need to know when to persist/restore, persisting myself on disk is fine for me.
That's not my issue. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
@Takhion Please take a look at flutter/engine#4358 |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
stanmots
Dec 3, 2017
I see you are mostly talking about Android platform here. But, actually, iOS also has somewhat similar mechanism to save/restore UI state when the app was killed for some reason. For example, when the user switches to a different app the current app is suspended and can be even killed because of memory constraints. You can find more info about this process in the official docs.
iOS developers expect this preserving/restoring procedure to be almost automatic. I guess, if your goal is to make truly cross-platform framework you should definitely take this into account.
stanmots
commented
Dec 3, 2017
|
I see you are mostly talking about Android platform here. But, actually, iOS also has somewhat similar mechanism to save/restore UI state when the app was killed for some reason. For example, when the user switches to a different app the current app is suspended and can be even killed because of memory constraints. You can find more info about this process in the official docs. iOS developers expect this preserving/restoring procedure to be almost automatic. I guess, if your goal is to make truly cross-platform framework you should definitely take this into account. |
Hixie
added
the
f: routes
label
Feb 6, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Zhuinden
Feb 24, 2018
You'd think something that intends to target Android as a platform at least attempts to obey the basics of the Activity contract....
Zhuinden
commented
Feb 24, 2018
•
|
You'd think something that intends to target Android as a platform at least attempts to obey the basics of the Activity contract.... |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
saket
commented
Feb 28, 2018
|
@Zhuinden let's not complain about things that are still in beta? :) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
aegis123
Feb 28, 2018
Other synchronous api's are onLowMemory and onTrimMemory and onConfigurationChanged don't know if IOS also has similar api's or mechanisms
aegis123
commented
Feb 28, 2018
•
|
Other synchronous api's are |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
lukaspili
Feb 28, 2018
Contributor
We may not want to reproduce the flawed android save&restoration mechanism on Flutter: You cannot save the whole state in the bundle because of the transaction size limit.
On android, you end up having multiple state save/restoration logics:
- developer's savedInstanceState, but you can't store large objects inside, like a list of elements
- database, where you can store large objects
- most widgets also manage their own state
- activity/fragment stack
It's really easy for developers to implement messy and buggy logic. In my own experience, it's really rare to see state save&restoration done right.
On flutter, the developer's state is the single source of truth.
Developers should persist this state into disk when it changes, without going trough the limited native platform mechanics.
Sure, you won't be able to easily save the scroll position, but who cares.
Most of the time, good UX for restoration means that the user should see the same screen than he was on previously. You can already do this with Flutter today.
Bottom point: there is room for improvement on the Flutter side in order to make state save/restoration less boilerplate (for things like Navigator). But I don't think it should provide hook to platform save/restore state.
|
We may not want to reproduce the flawed android save&restoration mechanism on Flutter: You cannot save the whole state in the bundle because of the transaction size limit. On android, you end up having multiple state save/restoration logics:
It's really easy for developers to implement messy and buggy logic. In my own experience, it's really rare to see state save&restoration done right. On flutter, the developer's state is the single source of truth. Sure, you won't be able to easily save the scroll position, but who cares. Bottom point: there is room for improvement on the Flutter side in order to make state save/restoration less boilerplate (for things like Navigator). But I don't think it should provide hook to platform save/restore state. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
saket
Mar 1, 2018
Sure, you won't be able to easily save the scroll position, but who cares.
Everyone? I'd be really frustrated if the app resets its list everytime I accidentally trigger an orientation change. :p
saket
commented
Mar 1, 2018
•
Everyone? I'd be really frustrated if the app resets its list everytime I accidentally trigger an orientation change. :p |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
mravn-google
Mar 1, 2018
Contributor
@Saketme FWIW, Flutter does not reset scroll positions on orientation change.
|
@Saketme FWIW, Flutter does not reset scroll positions on orientation change. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
LouisCAD
Mar 1, 2018
Using a Flutter app with a bit of multitasking should be fun on an Android Go device! Progress lost everytime the 1GB of RAM or less are under pressure
LouisCAD
commented
Mar 1, 2018
|
Using a Flutter app with a bit of multitasking should be fun on an Android Go device! Progress lost everytime the 1GB of RAM or less are under pressure |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
lukaspili
Mar 1, 2018
Contributor
@Saketme: as @mravn-google said, Flutter is not bound to configuration changes like android Activities.
The only state management needed is when app is killed by the OS while being in background.
@LouisCAD Sure state save&restoration is important.
Flutter developers can already implement most of this logic themselves, and Flutter should probably provide ways to make it less boilerplate. However the mechanism offered by Android is flawed and we could take the opportunity with Flutter to design something better, rather than hacking into Activity onSaveInstanceState / onRestoreInstanceState.
|
@Saketme: as @mravn-google said, Flutter is not bound to configuration changes like android Activities. @LouisCAD Sure state save&restoration is important. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
nsreenath
Mar 5, 2018
What's current the status of this issue?
Consider the case of a chat app, where I am typing a long message in the TextField.
Suddenly I receives a phone call and after some time, the OS kills the chat app due to low memory.
After the phone call, I come back to the chat app. Will Flutter automatically persist and recreate the message I was typing? or The app has to persist and recreate it manually?
Other than scroll position and route, what else are "states" that are not usually managed by developers?
nsreenath
commented
Mar 5, 2018
•
|
What's current the status of this issue? Consider the case of a chat app, where I am typing a long message in the Other than scroll position and route, what else are "states" that are not usually managed by developers? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
LouisCAD
Mar 5, 2018
@nsreenath Any chat app should persist messages draft by itself every few characters and when going to background. You may type a long message, and if the device shutdown for some reason, you'd not want to lose your progress on this. Android instance state is for light user input and progress into the screens
LouisCAD
commented
Mar 5, 2018
|
@nsreenath Any chat app should persist messages draft by itself every few characters and when going to background. You may type a long message, and if the device shutdown for some reason, you'd not want to lose your progress on this. Android instance state is for light user input and progress into the screens |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Zhuinden
Mar 5, 2018
I actually slept on this and I came to the realization that it's actually quite easy for Flutter devs to detect if the application came back from process death or is completely new instance.
Very simple, as long as they check for savedInstanceState == null (assuming they put at least 1 item in the onSaveInstanceState(bundle)). If a static boolean flag isFirstInit == false and savedInstanceState != null, then it's after process death.
Then they can create any kind of serialization / deserialization callback for complex state which could be cleared automatically when they detect savedInstanceState == null. That way they only need to persist some random boolean, but can manage their own persistence system.
Zhuinden
commented
Mar 5, 2018
•
|
I actually slept on this and I came to the realization that it's actually quite easy for Flutter devs to detect if the application came back from process death or is completely new instance. Very simple, as long as they check for Then they can create any kind of serialization / deserialization callback for complex state which could be cleared automatically when they detect |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
stanmots
Mar 5, 2018
Very simple, as long as they check for savedInstanceState == null (assuming they put at least 1 item in the onSaveInstanceState(bundle)).
There is no savedInstanceState and onSaveInstanceState on iOS. But the app can still be killed by OS.
Consider a typical workflow:
- A user goes to a specific screen inside the app
- Then the user switches to another app
- Suddenly the wise OS decides to kill the previous app to preserve the memory
- The user returns to the previous app but she sees the home screen. Not the screen that was open when she decided to switch the app
So, what is currently the recommended way to preserve the screen history in Flutter?
P.S. Of course, this is not important if your app has just one screen
stanmots
commented
Mar 5, 2018
There is no Consider a typical workflow:
So, what is currently the recommended way to preserve the screen history in Flutter? P.S. Of course, this is not important if your app has just one screen |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
lukaspili
Mar 5, 2018
Contributor
@Zhuinden I fail to see many scenarios where that's needed anyway.
a) Chat example:
Always save and restore previous content written in the text field that was not sent.
b) Long form example:
- Always save the content
- When user comes back to the form screen, notify the user there is a draft version that was saved but not submitted, asking if he wants to restore it. It does not make any difference if user exited the form manually (maybe ask if user wants to save draft) or if the app was killed while in background.
There are probably some cases where specific knowledge of "fresh new screen" vs "new screen after process death" is useful, but that might not be so common when you design your app's content to be always backed by a database.
@storix You need to manually persist the current route and restore it when app launches again. Too much boilerplate for a common use case, I agree. But still doable.
Also: Many android devs would be surprised by how few iOS apps/devs bother with state restoration. Majority of devs I know is not even aware that's an issue. Guess it's the luxury of working on higher end devices only.
|
@Zhuinden I fail to see many scenarios where that's needed anyway. a) Chat example: b) Long form example:
There are probably some cases where specific knowledge of "fresh new screen" vs "new screen after process death" is useful, but that might not be so common when you design your app's content to be always backed by a database. @storix You need to manually persist the current route and restore it when app launches again. Too much boilerplate for a common use case, I agree. But still doable. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
zoechi
Mar 5, 2018
Contributor
@Zhuinden the lifecycle callbacks from #6827 (comment) worked for my chat application. I just save some state every time when the app is switched to background. See also https://docs.flutter.io/flutter/dart-ui/AppLifecycleState-class.html
|
@Zhuinden the lifecycle callbacks from #6827 (comment) worked for my chat application. I just save some state every time when the app is switched to background. See also https://docs.flutter.io/flutter/dart-ui/AppLifecycleState-class.html |
Hixie
self-assigned this
Mar 6, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jules15
Mar 6, 2018
I would like to urge the Flutter team not to expose Android/iOS lifecycle methods as the canonical way of persisting/restoring UI state. Even in native apps, they were difficult to grok and code correctly, and the line between UI and application state was often blurry, with different mechanisms provided for each. It would be a shame to promulgate all of these disparate APIs into Flutter (especially if additional platforms are targeted in the future).
Flutter's stateless widgets have already migrated the responsibility for UI state out of the widgets and into the app, so the problem of persisting/restoring UI state is increasingly covered by persisting/restoring app state instead. I see this as a good thing, as opposed to treating UI and App state differently, as in iOS and Android.
I notice that some Flutter widgets, like ScrollView and TextField, provide "Controller" classes that encapsulate the dynamic state of the widget. In some ways they are acting as "memento" objects -- a snapshot of the widget's state -- which can be provided back to the widget at a later time to restore their state to some previous configuration. Sounds familiar. If these "mementos" were made easy to persist/restore, then an application could take responsibility for them as part of managing its own state. This would end the app/UI state dichotomy, would be opt-in, and would obviate the need for the Flutter framework to provide UI state preservation hooks (less is more!)
In other words, make it the developer's responsibility, but try to make it as easy as possible. If a developer thinks that a half-completed form is important enough for Flutter to persist across invocations, then one could argue that it's probably important enough to be considered application state. I realize that persisting the state of objects introduces versioning issues, but I think this is a more manageable problem.
jules15
commented
Mar 6, 2018
|
I would like to urge the Flutter team not to expose Android/iOS lifecycle methods as the canonical way of persisting/restoring UI state. Even in native apps, they were difficult to grok and code correctly, and the line between UI and application state was often blurry, with different mechanisms provided for each. It would be a shame to promulgate all of these disparate APIs into Flutter (especially if additional platforms are targeted in the future). Flutter's stateless widgets have already migrated the responsibility for UI state out of the widgets and into the app, so the problem of persisting/restoring UI state is increasingly covered by persisting/restoring app state instead. I see this as a good thing, as opposed to treating UI and App state differently, as in iOS and Android. I notice that some Flutter widgets, like ScrollView and TextField, provide "Controller" classes that encapsulate the dynamic state of the widget. In some ways they are acting as "memento" objects -- a snapshot of the widget's state -- which can be provided back to the widget at a later time to restore their state to some previous configuration. Sounds familiar. If these "mementos" were made easy to persist/restore, then an application could take responsibility for them as part of managing its own state. This would end the app/UI state dichotomy, would be opt-in, and would obviate the need for the Flutter framework to provide UI state preservation hooks (less is more!) In other words, make it the developer's responsibility, but try to make it as easy as possible. If a developer thinks that a half-completed form is important enough for Flutter to persist across invocations, then one could argue that it's probably important enough to be considered application state. I realize that persisting the state of objects introduces versioning issues, but I think this is a more manageable problem. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
NathanaelA
referenced this issue
Mar 13, 2018
Open
[Enhancement] Ability to trap and handle the OnSaveInstanceState on the Dart side #15478
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
gitspeak
Mar 20, 2018
Has there been any progress on this matter? I think there is a real need to distinguish between 'first run' and 'restored' process state. How else can you program to show the right screen when the user navigates back to a killed process?
gitspeak
commented
Mar 20, 2018
|
Has there been any progress on this matter? I think there is a real need to distinguish between 'first run' and 'restored' process state. How else can you program to show the right screen when the user navigates back to a killed process? |
championswimmer
referenced this issue
Apr 20, 2018
Open
Would like instructions on how to implement onSaveInstanceState #16799
matthew-carroll
added this to To do
in Platform Embeddings Refactor
via automation
Aug 7, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
rooton
Aug 14, 2018
@lukaspili you wrote: "The only state management needed is when app is killed by the OS while being in background."
Okey, then what about router stack, also save to disc? Also I dont find proper solution to determine that application was restored. Every time when app goes to background I need to save router stack, app data, state to disc? What if I dont use Redux?
rooton
commented
Aug 14, 2018
•
|
@lukaspili you wrote: "The only state management needed is when app is killed by the OS while being in background." Okey, then what about router stack, also save to disc? Also I don |
zoechi
referenced this issue
Aug 22, 2018
Open
Flutter app restarts when it is launched again from Recent apps after few seconds #20897
matthew-carroll
moved this from To do
to Architecture
in Platform Embeddings Refactor
Sep 13, 2018
This was referenced Sep 25, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
sir-boformer
Sep 26, 2018
Contributor
I think as a first step, we should give plugins the possibility to save and restore state. Here is my proposal: #22328
|
I think as a first step, we should give plugins the possibility to save and restore state. Here is my proposal: #22328 |
LouisCAD commentedNov 12, 2016
What is instance state, and why it exists
On Android, an Activity can be killed at any time by the system. This happens usually when Android needs memory when your Activity is not in the foreground, or because of a non-handled configuration change, such as a locale change.
To avoid the user having to restart what he did from scratch when Android killed the Activity, the system calls
onSaveInstanceState(…)when the Activity is paused, where the app is supposed to save it's data in aBundle, and passes the saved bundle in bothonCreate(…)andonRestoreInstanceState(…)when the task is resumed if the activity has been killed by the system.The issue about it in flutter
In the flutter apps I tried (Flutter Gallery, and the base project with the FAB tap counter), if I open enough apps to make Android kill the flutter app's Activity, all the state is lost when I come back to the flutter activity (while not having remove the task from recents).
Steps to Reproduce
This will allow to simulate when Android kills Activities because it lacks memory and you're not in the foreground.
What's expected: The app is in the same state that where we left off, with untouched UI.
What happens: The activity is restarted from scratch, losing all the UI state, even really really long forms.