Simulate killing of activity in emulator
Asked Answered
A

7

28

I would like to test out onSaveInstanceState and 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

Aculeate answered 13/3, 2011 at 3:39 Comment(0)
R
26

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.

Ruler answered 13/3, 2011 at 4:2 Comment(7)
thanks for the answer, I'm looking at the android developer adb's page and couldn't really find anything regarding killing the app process, would be grateful if you could elaborate more on that topic. Thanks!Aculeate
Got it, used ps to get the PID and kill <pid>Aculeate
just if someone else stumbles upon this like me: see developer.android.com/guide/developing/debugging/index.html > Debugging Tips (required commands are adb shell, ps, kill pid)Enteron
this is a really useful tip, thanks. P.S If you are using eclipse you can kill the process from the DDMS perspective.Pulliam
@RossScott - You can also do it from the Devices view in the Java perspective.Ruler
@TedHopp this is not simulating low memory conditions per se. just simulating calling of onSaveInstanceState. subtle difference. See my answer below for details.Edouard
@numan - You are correct that it does not simulate low memory per se. However, it does simulate the OS killing off a background app, whether due to low memory or any other reason. The way OP phrased the question suggests, I think, that this is the required test. Simply reorienting the app (as you suggest in your answer) will not test the effects of recreating the Application object (which OP specifically mentioned).Ruler
P
21

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.

Perseid answered 14/9, 2017 at 19:57 Comment(0)
U
15

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: http://bricolsoftconsulting.com/how-to-test-onsaveinstancestate-and-onrestoreinstancestate-on-a-real-device/

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.

Unbrace answered 23/12, 2011 at 22:42 Comment(6)
This is the best answer, thank you. Its very useful. Killing with adb works, but is awkward and debugger stopped working to me, so you coudn't check what was happening in onRestoreInstanceStateDafodil
Agree, this is the best way to go. It allows you to correctly test the full life cycle of activities.Etheleneethelin
@Unbrace this is not simulating low memory conditions per se. just simulating calling of onSaveInstanceState. subtle difference. See my answer below for details.Edouard
I didn't know that and it provided me with a way to reproduce issues I couldn't reproduce on any of my devices. Great tip!Sadoff
Better yet, Galaxy Nexus have an option "Don't keep activities" in Developer options. You'll have to unlock them first if over 4.2Sadoff
Note that the SetAlwaysFinished utility requires a rooted device when running under 4.1 or later. Also, I believe that this does not restart the entire app's process the way Android would have to recover resources, so it won't help to detect bugs caused by incorrect re-initialization of static variables (singletons, etc.) Killing off the entire process through adb (after pausing all activities) will test this aspect of your code. (You can also do it without adb by going to Manage Apps and forcing your app to stop.)Ruler
D
6

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.

enter image description here

Dreyfus answered 22/6, 2016 at 20:56 Comment(0)
E
5

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")

Edouard answered 24/2, 2013 at 2:39 Comment(0)
C
0

From android doc, http://developer.android.com/reference/android/content/ComponentCallbacks.html#onLowMemory()

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")

Crumley answered 13/3, 2011 at 3:55 Comment(0)
J
0

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 onCreate.

Ensure Activity has not defined below attribute on AndroidManifest.xml

android:configChanges="orientation"
Jehiah answered 28/5, 2015 at 9:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.