Skip to main content

App processes and startup — overview

The most important rule​

Android owns your application process. It creates the process when an app component needs to run and may remove a background process when the device needs resources.

Your application therefore has no permanent, app-controlled main() process. An Activity, Service, Receiver, or Provider can be the reason Android starts it.

Installed application ≠ running process

The app can be installed for months while its process is created and killed many times.

What a process contains​

A running app process contains:

  • its own virtual address space and managed heap;
  • ART runtime state;
  • a main thread and any worker threads;
  • loaded application and library classes;
  • static fields, Kotlin object instances, and dependency graph objects;
  • live Android component instances.

When the process dies, all of those in-memory objects disappear together.

Process lifetime and component lifetime differ​

Process created
├─ Application created
├─ Activity A created
├─ Activity B created
├─ Activity A destroyed
└─ process later killed

Destroying one Activity does not imply process death. Process death destroys every object in the process, even if a final callback such as onDestroy() was never delivered.

Startup states​

Android’s startup documentation distinguishes three useful states:

StateWhat is already available?Work typically required
ColdNo app processCreate process, Application, Activity, UI, first frame
WarmSome process/task state may exist, Activity needs creationRecreate Activity and UI
HotProcess and Activity remainBring existing Activity forward

These are performance categories, not guarantees about your exact object graph. Optimize and test cold start because it includes the most work.

Simplified cold-start path​

User taps icon / notification / deep link
↓
System resolves component and task
↓
App process requested from Zygote
↓
Main thread and runtime prepared
↓
Application object created
↓
App ContentProviders initialized
↓
Entry Activity created
↓
First frame drawn (TTID)
↓
Critical content becomes usable (TTFD)

This ordering explains why an SDK initialized by a ContentProvider can delay startup even when you never called it from Application.onCreate().

TTID and TTFD​

  • Time to initial display (TTID): time until the first frame appears.
  • Time to full display (TTFD): time until the experience is meaningfully ready for interaction.

A fast splash/empty frame can improve TTID while data remains unusable for seconds. Measure both. Product quality is not achieved by gaming the first-frame metric.

Real scenario: notification tap after process death​

The user receives an order notification, leaves the phone overnight, and taps it in the morning. The process no longer exists.

❌ Fragile design​

object SelectedOrder {
lateinit var order: Order
}

class OrderActivity : AppCompatActivity() {
override fun onCreate(state: Bundle?) {
super.onCreate(state)
render(SelectedOrder.order)
}
}

The singleton is a new empty instance in the new process. Accessing order crashes.

✅ Process-safe entry point​

class OrderActivity : AppCompatActivity() {
override fun onCreate(state: Bundle?) {
super.onCreate(state)

val orderId = intent.getStringExtra("orderId")
?.takeIf { it.matches(Regex("ORD-[0-9]+")) }
?: return finish()

viewModel.load(orderId)
}
}

The Intent carries a small stable identifier. The ViewModel asks a repository to reload durable truth.

What belongs where?​

StateExampleAppropriate home
Ephemeral UIExpanded card, selected tabrememberSaveable/SavedStateHandle when restoration matters
Screen stateLoading/error/content derived for UIViewModel, reconstructed from saved/durable inputs
Durable local business dataDraft order, downloaded messagesRoom/DataStore/file according to structure
Server authorityPayment result, inventoryBackend plus local synchronized representation
Process cacheDecoded image, computed lookupMemory cache; correctness cannot depend on survival

Multiple processes​

Manifest android:process can place a component in another process. That process has another heap, Application initialization, singleton set, threads, and failure lifetime.

❌ Incorrect assumption​

object LoginSession { var token: String? = null }

Two processes have two LoginSession objects.

✅ Architectural rule​

Use multiple processes only for a concrete isolation or integration requirement. Define process-safe storage/IPC and ensure libraries do not initialize incorrectly in every process.

Interview-ready answer

Android creates an application process when a component needs to run and can later kill a background process without final cleanup callbacks. Cold startup creates the process, Application, component, UI, and first frame; warm and hot starts reuse progressively more state. I treat all in-memory objects as disposable, pass stable IDs into entry points, save only small restorable UI state, persist durable business data, and keep eager startup work minimal.

Continue​

  1. Zygote and app-process creation
  2. Startup performance, TTID, and TTFD
  3. Process death and state restoration