Home » Android » How to simulate Android killing my process

How to simulate Android killing my process

Posted by: admin March 10, 2020 Leave a comment

Questions:

Android will kill a process if it is in the background and the OS decides it needs the resources (RAM, CPU, etc.). I need to be able to simulate this behaviour during testing so that I can ensure that my application is behaving correctly. I want to be able to do this in an automated way so that I can test if the application behaves correctly whenever this happens, which means that I’ll have to test this in every activity, etc.

I know how to kill my process. That isn’t the problem. The problem is that when I kill my process (using DDMS, adb shell kill, Process.killProcess(), etc.) Android does not restart it the same way that it would if the Android OS had killed it itself.

If the Android OS kills the process (due to resource requirements), when the user returns to the application Android will recreate the process and then recreate the top activity on the activity stack (calling onCreate()).

On the other hand, if I kill the process, Android assumes that the activity on the top of the activity stack was badly behaved, so it automatically recreates the process and then removes the top activity from the activity stack and recreates the activity that was underneath the top activity (calling onCreate()`). This is not the behaviour I want. I want the same behaviour as when Android kills the process.

Just to explain pictorially, if my activity stack looks like this:

    ActivityA -> ActivityB -> ActivityC -> ActivityD

If Android kills the process and the user returns to the application, Android recreates the process and creates ActivityD.

If I kill the process, Android recreates the process and creates ActivityC.

How to&Answers:

The best way to test this for me was doing this:

  • Open ActivityD in your application
  • Press Home button
  • Press Terminate Application in Logcat window in Android Studio (this will kill the app process, make sure you select your device and process in Logcat dropdowns at top)
  • Get back to the application with Home long press or opened apps (depends on the device)
  • Application will start in recreated ActivityD (ActivityA, ActivityB, ActivityC are dead and will be recreated when you get back to them)

On some devices you can also get back to application (ActivityD) with Applications -> Your launcher icon but on other devices it will start the ActivityA instead.

This is what Android docs are saying about that:

Normally, the system clears a task (removes all activities from the stack above the root activity) in certain situations when the user re-selects that task from the home screen. Typically, this is done if the user hasn’t visited the task for a certain amount of time, such as 30 minutes.

Answer:

This seems to work for me:

adb shell am kill <package_name>

This is different to adb shell kill mentioned by the OP.

Note that the help for the am kill command says:

am kill: Kill all processes associated with <PACKAGE>.  Only kills.
  processes that are safe to kill -- that is, will not impact the user
  experience.

So, it won’t kill the process if it is in the foreground. This seems to work as the OP wanted in that if I navigate away from my app, then run adb shell am kill <package_name> it will kill the app (I’ve confirmed this using ps on the device). Then if I return to the app I’m back in the activity I was in previously – i.e. in the OP’s example the process gets recreated and creates ActivityD (rather than ActivityC like most other methods of killing seem to trigger).

Sorry I’m a couple of years late for the OP, but hopefully others will find this useful.

Answer:

Another method, probably one that is scriptable since it doesn’t require DDMS:

One time setup: go to Developer Options, select Background process limit setting, change value from ‘Standard Limit’ to ‘No background processes’.

When you need to restart the process, press the home button. The process will be killed (you can verify in logcat/Android Monitor in studio — the process will be marked [DEAD]). Then switch back to the app using the task switcher.

Answer:

This question is old but, there is an answer for this question which does not require adb, Android Studio etc. The only requirement is API 23 or newer.

To simulate app restart by OS, go app settings while your app is running, disable (then you can enable) a permission and return the app from recent apps. When permission is disabled, the OS kills the app but keeps saved instance states. When user returns the app, the app and the last activity (with saved state) are recreated.

‘No background processes’ method sometimes causes same behavior, but not always. For example, if the app is running a background service, “No background processes” does nothing. But the app can be killed by system including its services. Permission method works even if app has a service.

Example:

Our app has two activities. ActivityA is main activity which is started from launcher. ActivityB is started from ActivityA. I will show only onCreate, onStart, onStop, onDestroy methods. Android calls onSaveInstanceState always before calling onStop, because an activity which is on stop state can be killed by system. [https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle]

Permission method:

<start app from launcher first time>
Application onCreate
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
<open ActivityB>
ActivityB onCreate WITHOUT savedInstance
ActivityB onStart
ActivityA onStop (the order is like this, it is stopped after new one is started)
<go settings>
ActivityB onStop
<disable a permission>
//Application is killed, but onDestroy methods are not called.
//Android does not call onDestroy methods if app will be killed.
<return app by recent apps>
Application onCreate (this is the important part. All static variables are reset.)
ActivityB onCreate WITH savedInstance (user does not notice activity is recreated)
//Note that ActivityA is not created yet, do not try to access it.
ActivityB onStart
<return ActivityA by back>
ActivityA onCreate WITH savedInstance (user does not notice activity is recreated)
ActivityA onStart
ActivityB onStop
ActivityB onDestroy
<press back again, return launcher>
ActivityA onStop
ActivityA onDestroy
<open app again>
//does not call Application onCreate, app was not killed
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart

I want to compare other methods which are mentioned on the other answers.

Do not keep activities: This does not kill application.

<start app from launcher first time>
Application onCreate
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
<open ActivityB>
ActivityB onCreate WITHOUT savedInstance
ActivityB onStart
ActivityA onStop
ActivityA onDestroy (do not keep)
<return launcher by home button>
ActivityB onStop
ActivityB onDestroy (do not keep) 
<retun app from recent apps>
// NO Application onCreate
ActivityB onCreate WITH savedInstance (user does not notice activity recreated)
ActivityB onStart
<return ActivityA by back>
ActivityA onCreate WITH savedInstance (user does not notice activity recreated)
ActivityA onStart
ActivityB onStop
ActivityB onDestroy
<press back again, return launcher>
ActivityA onStop
ActivityA onDestroy
<open app again>
//does not call Application onCreate, app was not killed
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart

Force stop method: Does not store saved instance states

<start app from launcher first time>
Application onCreate
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
<open ActivityB>
ActivityB onCreate WITHOUT savedInstance
ActivityB onStart
ActivityA onStop
<go settings>
ActivityB onStop
<force stop, return app from recent apps>
Application onCreate
ActivityA onCreate WITHOUT savedInstance 
//This is important part, app is destroyed by user.
//Root activity of the task is started, not the top activity.
//Also there is no savedInstance.

Answer:

I’m very late to the party and several before me gave the same correct answer but to simplify for whoever comes after me just press home button and run this command:

adb shell ps | grep <package name> | awk '{print $2}' | xargs adb shell run-as <package name again> kill

The app won’t lose state and from my own experience this works the same way as the OS killed the app in the background. This works only for debug built applications

Answer:

This is how you do it in Android Studio.

  1. Have your device in Debug Mode connected to your computer.
  2. Open the app on your device and go to whichever activity you want to test the “Return to it from the dead”.
  3. Press Home button on your device.
  4. In Android Studio go to Android Monitor -> Monitors and press the Terminate Application icon.
  5. Now you can either go back to your app through the recent apps or by clicking on it’s launcher icon, behaviour has been the same in my tests.

Answer:

In the Developer options under Settings, select ‘Do not keep activities’, which will destroy activities as soon as you navigate away from them.

Answer:

Put the application in background with HOME button

Select your process in “Logcat” mode in Android Studio, then click Terminate Application in the bottomleft corner

terminate button

Now launch your app from launcher on Android device


EDIT: According to the internet, the following also works:

 adb shell am kill [my-package-name]

Answer:

You can do next steps to reproduce sought-for behaviour:

  1. Open your app, navigate to top activity
  2. Use notification panel to navigate to any another full-screen application (for example, to system settings – in right top corner)
  3. Kill your application process
  4. Press back button

Answer:

Press the Home button and put the app in the background first. Then stop or kill the process from DDMS or ADB.

Answer:

You can also connect to your device/emulator from terminal with adb shell, then get PID of your process with ps | grep <your_package_name and execute kill -9 <pid>. Then open your minimized app from recent apps picker and it will restart last activity

Answer:

The root of your problem seems to be that your Activity is in foreground when you kill the process.

You can observe this by pressing stop in DDMS when Activity is visible (happens exactly what you describe) and comparing that to pressing stop after home and later returning to the app.

Just make sure to moveTaskToBack(true) somehow in your tests.

Answer:

I’m not sure this is the answer you are looking for, it’s more like a logic think.

I don’t think that you can really make a fully automated test, the only way to simulate it, it will be to recreate it, AKA have so many activities that Android will kill your application.

So my idea or suggestion is to make another small app, which keeps popping up new activities, till Android runs out of memory and start killing process it the background.

Something among the line:

Start activity i -> Check running process if the app is in the list, increment i and restart the loop without closing current activity, else -> decrease i and close current activity, go back to previous and recheck…