I would like to test out
onRestoreInstanceState for my app on the emulator.
I have found this, which says that we could simulate this during orientation change, but I’m storing some of my variables on the application level (subclass
android.app.Application), so the orientation change does not wipe out the variables.
So my question is, how can I simulate the low memory situation thus killing of my activities?
Hope I’ve made myself clear. Thanks
You can pause your application (by pushing the Home button, simulating a call, whatever). Then kill the app’s process through adb. Since the docs say that after onPause() returns your app can be killed without any further notice, this is a fair test.
If you don’t want to go through the trouble of finding the pid of your app’s process, you can use
adb shell am kill com.example.package_name to kill your app’s process. Make sure that the app is put in the background. The docs say that this command “kills only processes that are safe to kill and that will not impact the user experience.” So you might want to launch a couple of other apps before trying this one.
To test the onSaveInstanceState and onRestoreInstanceState events you can use the SetAlwaysFinish utility (see link below). It uses a hidden system setting called Always Finish to change the behavior of the Android system. With the Always Finish option enabled, the Android OS will immediately unload any activity that moves from the foreground to the background, triggering its onSaveInstanceState event. Then, when the system needs the activity again, it is forced to reload it triggering the onRestoreInstanceState event.
The advantage of this method compared to killing the process is that it’s easier and you get finer control (activity level rather than process level).
See the blog post below for more details on the tool and how to use it:
The Always Finish feature is also present in the emulator in the DevTools app under Development Settings > Immediately destroy activities. However, the DevTools app does not work outside of the emulator.
There’s a more solid solution for this in Android 6 and newer. I’ve used the following method successfully on Android 6, 7, and 8:
1) Open your app, go to the activity that you want to test restoring, and then leave it by pressing the Home button
2) Open the Settings app, go to System -> Developer Options, then tap on “Running Services”
3) Tap on “Show Cached Processes” at the top right, then find your app in the list, tap on it, and then tap the “Stop” button.
4) Use the recent apps list to return to your app. It should relaunch the whole app on the activity that you had previously left it from.
I’ve found this to be sufficient to fully kill the app, including any app delegate stuff and the C/C++ native code state, and then test relaunching it with a saved activity state… This effectively replicates what happens when the user leaves the app for a while and then the system kills it to save memory, battery, or whatever.
You can use the setting “Don’t keep activities” in developer settings or kill the app process by yourself.
To kill the process, open the activity you want to test, then press home button to send your app to background, and then, using the DDMS in Android Studio (Android Device Monitor), select the process and then stop the process (as seen in the image below). Your app was killed. Now, open your app again (accessing the list of open apps). Now you can test the killed state.
Lets clarify your question.
But before we do that here is a fact about onSaveInstanceState – its gets called for various reasons such as:
- orientation change
- going from foreground to background (by clicking home or launching another activity or clicking recents)
- system is under low memory
Now, if your question is “how can i simulate the calling of onSaveInstance for just testing purposes” then Theo and Ted’s answer is correct. Both changing developer settings option or pressing home will result in onSaveInstance being called.
But so would just changing orientation (as you noted in your question) – which leads me to believe you might be asking “how can i simulate calling of onSaveInstance method when system is under low memory pressure”
The short answer to this question is there is no automated way to simulate low memory condition. The above mentioned techniques only simulate calling of the onSaveInstanceState method not low memory conditions per se
Couple of caveats here.
The first caveat to this is that under extreme conditions the kernel will “uncleanly” kill your process to claim memory – meaning onSaveInstanceState will never be called. In this situations testing onSaveInstanceState is moot. There isn’t much you can do about this scenario but the good news is that its a very rare event esp. for foreground activities.
The second caveat is that ActivityManager can reclaim your activity’s resource by “killing it cleanly” i.e. your onSaveInstance will get called. This happens to activities that are not in foreground (i.e. not visible to the user so already in stopped state) and the system is under memory pressure.
On this second caveat, again you can’t simulate this condition automatically. It can be done if you start bunch of heavy duty activities manually and hope the ActivityManager is forced to recycle one of your activities.
The bigger point to remember here is that there is no need to simulate low memory condition. As long as you are simulating how onSaveInstanceState is called you are automatically testing the condition where it might be called for low memory situations. And the easiest way to trigger this method is to change orientation on the emulator (ctrl-f11). And if you are using an actual device to temporarily change the developer settings (“Don’t keep activities”)
This is triggered by the system. I think you can set the device ram size lower during creating an android virtual device. (In Hardware, choose “Device ram size”)
The simplest solution which works for me is just change the orientation of the device (you can do that regardless you’re using AVD, Genymotion or any other emulator). By default system will recreate
Activity by calling
onDestory followed by
Activity has not defined below attribute on AndroidManifest.xml