Repository navigation
Instance state not saved when app is killed by OS #6827
Description
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 a Bundle, and passes the saved bundle in both onCreate(…) and onRestoreInstanceState(…) 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
- Install Flutter Gallery
- Open the device's settings, and in developer options, switch "Don't keep activities" on. (see the screenshot)
This will allow to simulate when Android kills Activities because it lacks memory and you're not in the foreground. - Open the Flutter Gallery app and go anywhere other than the main screen.
- Go to the launcher by pressing the device's home button.
- Press the overview button and return to Flutter Gallery. Here's the bug.
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.

Activity
eseidelGoogle commentedon Nov 12, 2016
#3427 is also likely related.
LouisCAD commentedon 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?
Hixie commentedon Nov 12, 2016
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.)
LouisCAD commentedon 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…?
Hixie commentedon Nov 14, 2016
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.
LouisCAD commentedon 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.
Takhion commentedon 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 inonSaveInstanceState?LouisCAD commentedon 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)
Takhion commentedon 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?
Hixie commentedon Sep 29, 2017
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.
sethladd commentedon Oct 7, 2017
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?
141 remaining items
goderbauer commentedon Jun 9, 2020
The design document with details about how to do state restoration in Flutter is available here: http://flutter.dev/go/state-restoration-design
goderbauer commentedon Jun 30, 2020
The PR with the general state restoration framework as outlined in the design above has been posted: #60375. I am still working on adding some more test coverage.
goderbauer commentedon Jul 29, 2020
The general state restoration framework (#60375) has been submitted. I am now working on integrating it in our widgets. Going to start with scrollables, text fields, and the Navigator.
gaaclarke commentedon Jul 31, 2020
You can implement this yourself by storing the data you want restored inside of a sqlite database. That's a technique that is used when writing servers.
That has the benefit of restoring an app even if the battery dies on the phone or there is a kernel panic or whatever. I recommend making an OO wrapper around your SQLite calls. Dart doesn't have something like SQLite.Net which does it automatically for you unfortunately.
edit: It's also something we did in the early days of mobile development because memory was so limited and sqlite is a great way to swap things between memory and disk.
goderbauer commentedon Aug 4, 2020
I am closing this issue since the general state restoration framework (and the Android embedding) has landed. The remaining work is tracked in separate issues:
luffyjie commentedon Oct 12, 2020
Well Done!!!!! Thanks flutter!!!
github-actions commentedon Aug 11, 2021
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.