How to Simulate Process Death in Android?

Explore Different Ways of Simulating Process Death Initiated by the Android Operating System and the User

ยท

5 min read

How to Simulate Process Death in Android?

There are 2 types of process death in Android:

  • System-initiated Process Death
  • User-initiated Process Death

System-initiated process death means the process is killed by the Android operating system. It could be due to resource constraints (not enough memory) or simply configuration changes (screen rotation).

User-initiated process death means the process is killed by the user. For example, you click the home button, and manually close the background app.

Usually as a developer, you care about only the system-initiated process death because you're required to save the UI state. For user-initiated process death, you do NOT need to save the UI states.

System-initiated Process DeathUser-initiated Process Death
Required to save UI statesNOT required to save UI states

For saving UI states expectation, you can refer to the official documentation here.

System-initiated Process Death

1. Use Logcat Terminate App Button

The easiest way to simulate system-initiated process death, use the Logcat terminate app button.

  • You press the home button.
  • Then, use the Logcat terminate app button as shown below.

Activity_and_ViewModel_Lifecycle_Demo_App_01.png

Wait, this "Terminate App" button has been REMOVED in Android Studio Dolphin. See the issue tracker here.

According to the ticket, it has been moved to Device Monitor in Android Studio Flamingo version. I just tried, it does NOT work! It can NOT be used to replace this Logcat Terminate App Button!

Force Stop in Device Monitor != Logcat Terminate App

In device monitor (Android Studio Flamingo), there are 2 options

  • Kill process - equivalent to adb shell am kill command
  • Force stop process - equivalent to adb shell am force-stop command

How to Simulate Process Death in Android 001.png

Kill process does nothing because the device is not rooted.

Force stop process does kill the process, BUT it does NOT simulate system-initiated process death. It simulates user-initiated process death, which is exactly the same as using adb shell am force-stop command - see below.

So, this is not what we want. Even if you upgrade to this Android Studio Flamingo version, you won't able to use Device Monitor to simulate system-initiated process death.

2. Set No Background Processes - Developer Options

The only workaround that I am aware is set no background processes in developer options. To enable developer options, you refer to the step here.

  • Go to Setting -> System -> Developer Options (depends on Phone, Developer Options could be at different location)
  • In Apps, Background process limit, select No background processes

How to Simulate Process Death in Android 00.png

To simulate system-initiated process death, once you have launched your app

  • Press the Home button
  • Launch other app and press the Home button

Your app process will be killed. You should be able to see that in your Logcat if you're using Android Studio Dolphin.

PROCESS ENDED (8227) for package com.example.understandlifecyclesdemo

You can also inspect the process using the adb shell ps in Android Studio terminal and make sure your app package is no longer shown up in the process list.

I just tried this method and it doesn't seem to work on API Level 33. The process is still at the background. It worked on API level 26 at least (the API level that I've tried sucessfully).

User-initiated Process Death

The easiest way to simulate user-initiated process death is doing exactly what user can do.

1. Manually Close the App

  • Press the Home button
  • Press the Square button
  • Close the App - press the X or CLEAR ALL

How to Simulate Process Death in Android 01.gif

2. adb shell am force-stop

Another way is using the adb command in the terminal. You can run this command even your app is in foreground. It will just kill your app directly.

adb shell am force-stop <applicationId>

The applicationId is the one you define in the build.gradle app level. Please note, it is NOT your package name.

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.example.understandlifecyclesdemo"

        /*...*/
    }
}

So the full command looks like this based on the above applicationId name.

adb shell am force-stop com.example.understandlifecyclesdemo

Similar to above, you can check whether the process has been successfully killed using this command adb shell ps.

I also try adb shell am kill <applicationId>. It doesn't work for me. Nothing happens, no errors. I think it requires your device to be rooted.

Process Death Recovery

While playing with saving UI states, I notice for user-initiated process death recovery, Android OS does NOT restore the UI states even you save data into the bundle before your app is killed. Specifically, Activity.onRestoreInstanceState() is not called. In Activity.onCreate(), the Bundle parameter is null.

For system-initiated process death recovery, Android OS restores the UI states if there are data being saved prior to process death. Specifically, Activity.onRestoreInstanceState() is called. In Activity.onCreate(), the Bundle parameter is NOT null.

This is similar to SavedStateHandle in your view model. For user-initiated process death recovery, retrieved value from SavedStateHandle is null even you save the data prior to that. For system-initiated process death recovery, the retrieved value is the previously saved value.

Here is the summary

System-initiated Process Death RecoveryUser-initiated Process Death Recovery
onRestoreInstanceState() is calledonRestoreInstanceState()is NOT called
Bundle is NOT null in onCreate()Bundle is null in onCreate()
SavedStateHandle.get() returns previously saved valueSavedStateHandle.get() returns null

SavedStateHandle in view model is seperated from the Bundle in the activity. Whatever being saved from the Bundle can NOT be retrieved from SavedStateHandle.

Conclusion

If you're on Android Studio Dolphin or later, the only way to simulate system-initiated process death is Set No Background Processes in Developer Options, but somehow it doesn't work on API level 33. So the workaround is to use API level 26. It may work on other API levels.

Source Code

GitHub Repository: Demo_UnderstandLifecycles

Did you find this article valuable?

Support Vincent Tsen - AndroidDev Blog by becoming a sponsor. Any amount is appreciated!

ย