How it works
The explanation, with examples you can run.
The importance ladder
When memory runs low the system picks victims by importance, roughly in this order from safest to most at risk:
- Foreground: an activity the user is interacting with (resumed), a broadcast receiver running
onReceive(), a service in the middle of a lifecycle callback, or a foreground service. - Visible: an activity on screen but not in focus (behind a dialog, or in multi-window), or a service the system uses for a feature the user sees, such as a live wallpaper or keyboard.
- Service: a service started with
startService(). Kept unless memory is needed for the two levels above, but a service that has run for a long time can be demoted. - Cached: nothing the user needs right now, typically only stopped activities. The system keeps several around for quick switching and kills them freely.
The kill is a plain signal to the process. onDestroy() is not called, and neither is anything else.
What a kill looks like to your code
From the user's side nothing happened: your app is still in Recents. When they tap it, Android starts a fresh process, creates your Application, and recreates the top activity with the Bundle it saved earlier. Static fields, singletons, in-memory caches and running coroutines are all gone.
object Session { // Lost on process death: the user returns to a screen that expects this to be set. var currentCart: Cart? = null}The fix is not to fight the system but to keep state somewhere that survives: small UI state in saved state (rememberSaveable, SavedStateHandle), real data on disk (Room, DataStore), and pending work in WorkManager.
Testing it
Rotating the device does not test process death; the process survives a rotation. To simulate the real thing, put the app in the background and run:
adb shell am kill com.example.app # only kills a process that is in the backgroundThen reopen it from Recents. Developer options also has "Don't keep activities", which destroys activities on leaving them (not quite the same as a process kill, but it exercises the restore path).
Listening for pressure
ComponentCallbacks2.onTrimMemory() tells you when the system is under pressure or your UI has been hidden (TRIM_MEMORY_UI_HIDDEN), which is a good moment to drop caches. It is a hint, not a promise: a process can be killed without seeing any level first.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.