How to Simulate Process Death in Android?
Explore Different Ways of Simulating Process Death Initiated by the Android Operating System and the User
Table of contents
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 Death | User-initiated Process Death |
Required to save UI states | NOT 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.
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
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
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
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 Recovery | User-initiated Process Death Recovery |
onRestoreInstanceState() is called | onRestoreInstanceState() is NOT called |
Bundle is NOT null in onCreate() | Bundle is null in onCreate() |
SavedStateHandle.get() returns previously saved value | SavedStateHandle.get() returns null |
SavedStateHandle
in view model is seperated from theBundle
in the activity. Whatever being saved from theBundle
can NOT be retrieved fromSavedStateHandle
.
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