I'm tracking down a bug that, on rare occasions, causes an app to crash when it is reactivated via the recent apps list after being in the background for a while. When this occurs, the call stack information indicates that the activity has not restored its instance state correctly. The necessary code for saving/restoring the state is in place - the state is saved in
onSaveInstanceState and restored in
onRestoreInstanceState in this case).
I'm aware of what Android is doing: It kills the app process at some point to conserve memory, and restarts it when I reactivate the app. But it appears that Android sometimes does not call onSaveInstanceState before killing the process, causing a
null Bundle to be passed to onCreate. This is fatal because from the app's point of view, it never stopped, but now its state is gone.
Any ideas how this can happen?
Another puzzling detail is that although the crash cannot (easily) be reproduced by killing the app's process via a task manager, it is consistently reproducible be setting the number of background processes to "none" in the device's developer options. (I know the entire process is actually killed in both scenarios, because when the app is restarted, I can see it waiting for the debugger to attach, which doesn't occur when the process is still alive).
In the case where no background processes are allowed, pressing the home button and reactivating the app via the recent app list is sufficient to reproduce the crash. Logging clearly indicates that
onSaveInstanceState is not called, and that a
null Bundle is passed to
According to the documentation,
onSaveInstanceState is always called before the system kills a process. Any ideas why it would not do so in this case?
What type of data are you trying to save? It's best to commit any long term data in
onPause() as there are cases where
onSaveInstanceState() may not get called. I would also recommend sanity checking the data so if you get nothing from the
Bundle it is handled gracefully. From the
"...Because of this, you should use the onPause() method to write any persistent data (such as user edits) to storage. In addition, the method onSaveInstanceState(Bundle) is called before placing the activity in such a background state, allowing you to save away any dynamic instance state in your activity into the given Bundle, to be later received in onCreate(Bundle) if the activity needs to be re-created. See the Process Lifecycle section for more information on how the lifecycle of a process is tied to the activities it is hosting. Note that it is important to save persistent data in onPause() instead of onSaveInstanceState(Bundle) because the latter is not part of the lifecycle callbacks, so will not be called in every situation as described in its documentation."