Android path · The process · Topic 1 of 12

Processes and why your app is killed

Not started

Every Android app runs in its own Linux process with its own runtime (ART). You never start or stop that process yourself: the system creates it when one of your components (an activity, a service, a broadcast receiver, a content provider) is needed, and it ends it when it wants the memory back. The process's lifetime is decided by what the user is doing, not by your code.

Why it matters: Android kills app processes routinely to free memory, without asking. An app that assumes it keeps running loses the user's work; one that expects to die restores it.

  1. 1The system owns the process

    Android starts your process when one of its components is needed and may end it whenever memory is short, with no callback.

  2. 2Importance decides who goes first

    Foreground beats visible, visible beats a started service, and cached processes are killed first and often.

  3. 3Plan for coming back

    When the user returns, Android starts a new process and recreates the screen; anything that only lived in memory is gone.

1

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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 background

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

2

Check yourself

3 questions. Get them all right to finish this topic.

  1. 1.The user is watching a video in another app. Your app is in the background with no running services. How is your process ranked?
  2. 2.Which callback reliably runs just before the system kills your process for memory?
  3. 3.Why does a long-running started service (without startForeground) not keep your app alive for good?

0 of 3 right so far. Get all three to finish this topic.