Zygote
Components & Intentsintermediate

Activities, tasks and the back stack

A task is a stack of activities the user thinks of as one thing. Launch modes and flags are the rules for putting activities into tasks — and every one of them is a trade-off about Back.

11 minAPI 1–37 · 17interactivequizverified 2026-10-27

Open a mail app, tap a message, tap a link, and you have three screens in a stack. Press Back three times and you are where you started. That stack is not a UI widget — it is a system-level data structure that system_server owns, and the app only asks to push and pop entries.

TL;DR#

  • A task is a stack of activities, usually experienced as one thing. The launcher starts one; each app can have several.
  • Back pops the current task. When the last activity in a task finishes, the task is removed and the previous task becomes visible.
  • Launch modes (standard, singleTop, singleTask, singleInstance) decide whether a new instance is created, reused, or placed in a separate task.
  • flags are per-launch overrides: NEW_TASK, CLEAR_TOP, CLEAR_TASK, SINGLE_TOP, NO_HISTORY.
  • The back stack is also the predictive back contract. Since Android 16 it is on by default for targeting apps, which means the system draws the destination before Back completes.1

Mental model#

Think of a stack of paper on a desk.

Each sheet is an . You can put a new sheet on top, take the top sheet off, or — with the right permission — reach down, pull out a sheet, and drop everything above it. The desk (a task) keeps its own pile. Several desks may be open in the room, but you are looking at one.

Where the analogy breaks#

The sheets are not static. An activity that is not on top may be destroyed while it sits in the pile, and when you take the sheet above it off, the system may rebuild it from a saved bundle. So the stack holds positions and saved state, not necessarily live objects. That is why "the activity below is still there" is a convenient lie and not a guarantee.

The big picture#

Loading diagram…
Text description of this diagram

An interactive task stack simulator. Five activities are available: MainActivity and DetailActivity in standard mode, SearchActivity in singleTop, InboxActivity in singleTask and PlayerActivity in singleInstance. Launch buttons push activities according to their launch mode, and toggles apply the flags FLAG_ACTIVITY_NEW_TASK, FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_CLEAR_TASK. The diagram draws each task as a horizontal row, with instances ordered left to right and the top of the stack marked. The event log explains each decision: a new instance pushed, an existing instance reused with onNewIntent, a task created, or activities cleared above an existing instance. A Back button pops the current task and removes it when it becomes empty.

Press Detail three times and watch three instances pile up. Then launch Inbox: a new task appears, because singleTask roots its own. Then launch Inbox again and nothing new is created — the existing task is brought forward and everything above the instance is cleared.

Deep dive#

A task is not an app#

The word "task" suggests "an app's windows", and that is usually true but not definitionally true. Activities from different apps can share a task (a share sheet is a task containing your activity and the target's), and one app can own several tasks.

ActivityTaskManagerService, inside system_server, owns the task list. Your app calls startActivity(); the service decides which task the new activity joins, what happens to the activities above it, and whether the process needs to be created.2

The four launch modes#

The mode lives in the manifest:

<activity
    android:name=".SearchActivity"
    android:launchMode="singleTop"
    android:exported="false" />
ModeBehaviourWhen it is right
standarda new instance every timethe default, and usually correct
singleTopreuse the instance if it is already on topsearch, notifications, a detail screen reachable repeatedly
singleTaskone instance, rooted in its own task; starting it again clears above itthe entry point of a feature, a "home" for a section
singleInstancelike singleTask, and no other activity may join its taskrare: a full-screen call UI or a launcher-like surface

singleTop is the only mode that does not surprise people. The other three change task structure, which means they change what Back does — and Back is a promise to the user.

// singleTop in action: a search result tap re-delivers to the same screen.
class SearchActivity : ComponentActivity() {
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)          // replace the intent the activity reports
        viewModel.onQuery(intent.getStringExtra(EXTRA_QUERY))
    }
}

Note setIntent. If you do not call it, getIntent() keeps returning the first intent, and a singleTop screen appears to ignore every subsequent launch. It is the single most common bug with this mode.

Flags: per-launch overrides#

Flags let a caller do something different without changing the manifest. They compose, and some of them only make sense together.

val intent = Intent(context, InboxActivity::class.java).apply {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or
            Intent.FLAG_ACTIVITY_CLEAR_TOP or
            Intent.FLAG_ACTIVITY_SINGLE_TOP
}
context.startActivity(intent)
  • FLAG_ACTIVITY_NEW_TASK — find or create a task whose root matches, then deliver there.
  • FLAG_ACTIVITY_CLEAR_TOP — if an instance exists in the task, remove everything above it. Combine with SINGLE_TOP to keep the instance and call onNewIntent instead of recreating it.
  • FLAG_ACTIVITY_CLEAR_TASK — clear the target task entirely; only meaningful with NEW_TASK.
  • FLAG_ACTIVITY_NO_HISTORY — the activity does not remain in the stack after the user leaves it.

Back, and what it means now#

Historically, Back was handled by the activity: onBackPressed() was called, and you could override it. That model could not support a gesture that shows the destination before you commit.

The modern API is OnBackPressedDispatcher:

class DetailActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
 
        onBackPressedDispatcher.addCallback(this) {
            if (hasUnsavedChanges()) {
                showDiscardDialog()
            } else {
                isEnabled = false
                onBackPressedDispatcher.onBackPressed()
            }
        }
    }
}

With predictive back, the system animates the destination during the gesture. To participate, an activity must declare android:enableOnBackInvokedCallback="true" (or the app-level equivalent), and navigation must go through the dispatcher so the system can see the destination ahead of time. Since Android 16, targeting apps have predictive back enabled by default rather than opting in.1

taskAffinity in practice#

taskAffinity defaults to the package name, which is why most apps have one task. Changing it separates an activity into its own task when launched with NEW_TASK:

<activity
    android:name=".PlayerActivity"
    android:taskAffinity="com.example.notes.player"
    android:launchMode="singleTask" />

That combination is the standard recipe for a "now playing" screen that must not stack: its own task, one instance, brought forward when the user taps it again. It is also the recipe for a surprising Recents screen, because the user now sees two cards for one app — which is correct if the two things genuinely are separate tasks.

The rule: change taskAffinity only when the user's mental model has two separate things. Otherwise the default is right.

Multi-window and multi-resume#

Since Android 10, two activities from different apps can be visible at once, and both can be resumed. That breaks the old assumption that at most one activity is resumed in the system, and it changes what "pause" means: an activity can be paused yet still fully visible.

A practical consequence: do not stop animations or release camera resources in onPause() alone. Ask whether the activity is still visible, or use a lifecycle-aware API that knows about multi-resume.

Recents is a different list#

The overview screen (Recents) is not the back stack. It lists tasks, one card per task, and its contents are governed by taskAffinity, documentLaunchMode and whether an activity opts out with android:excludeFromRecents.

That distinction explains a common complaint: an app can have a deep back stack and still show a single card in Recents, because Recents shows the task, not the activities inside it. Conversely, a browser with documentLaunchMode="intoExisting" can show one card per tab.

<activity
    android:name=".DocumentActivity"
    android:documentLaunchMode="intoExisting"
    android:excludeFromRecents="false" />

The four values of documentLaunchMode are none, intoExisting, always and never. always is what produces one Recents card per document, which is how a document editor models tabs.

Task affinity and documentLaunchMode#

Two more knobs exist and are worth knowing by name rather than by detail. taskAffinity names the task an activity prefers when launched with NEW_TASK; it defaults to the package name. And documentLaunchMode on an activity (with FLAG_ACTIVITY_NEW_DOCUMENT) gives each document its own entry in Recents — that is how browsers and document editors keep tabs in the overview screen.

How it evolved#

The task model has been stable since API 1, but the control over it has moved steadily from the app toward the system.

Interface changes16 releases
APIVersionWhat changed
11.0
  • Pull-down notification shade
  • Home screen with widgets
31.5 Cupcake
  • Home screen widgets and folders
92.3 Gingerbread
  • New UI with dark theme and green accents
113.0 Honeycomb
  • The Holo design language arrives
123.1 Honeycomb
  • Resizable widgets
164.1 Jelly Bean
  • Project Butter: vsync-driven, smooth UI
  • Expandable notifications
204.4W KitKat (Wear)
  • Voice-driven card UI
215.0 Lollipop
  • Material Design
  • Notifications on the lock screen
247.0 Nougat
  • Quick Settings tiles
  • Direct Reply in notifications
268.0 Oreo
  • Notification channels
289 Pie
  • Dark theme groundwork
2910
  • System-wide dark theme
3011
  • Conversation notifications and bubbles
  • Media controls in Quick Settings
3112
  • Material You dynamic colour
3313 Tiramisu
  • Themed app icons
  • Runtime notification permission
3616 Baklava
  • Material 3 Expressive
  • Live Updates notifications

The pattern: early Android let an app do almost anything to the stack; later releases added multi-window, then predictive back, then defaults that make the system's model authoritative.

Under the hood#

Curiosity corner#

  • Back can leave your app entirely. Popping the last activity of the last task returns to the launcher. There is no "exit" callback, which is why apps should save state as they go rather than at the end.
  • singleInstance is almost always the wrong answer. It exists for surfaces that genuinely must be alone, such as an incoming-call screen. Using it for a normal feature breaks sharing and Recents.
  • A task can outlive its process. The system remembers the stack and rebuilds activities from saved state after a kill.

Try it#

Print the current task stack

adb shell dumpsys activity activities | grep -E "Task|Hist"

Launch with a flag

adb shell am start -n com.example.notes/.InboxActivity --activity-clear-top

Check yourself#

Check yourself

1 / 12

You call `startActivity()` for an activity in another app. Which check does the system perform before delivering the intent?

0 answered · 0 correct

Sources#

Sources

Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.

  1. docsBehavior changes: Apps targeting Android 16 or higherdeveloper.android.comaccessed 2026-10-27↩
  2. docsالمهام وحزمة التطبيقات الخلفية | App architecturedeveloper.android.comaccessed 2026-10-27↩
  3. docsBehavior changes: Apps targeting Android 17developer.android.comaccessed 2026-10-27↩
  4. docs活動簡介 | App architecturedeveloper.android.comaccessed 2026-10-27↩
  5. docsIntents and intent filters | App architecturedeveloper.android.comaccessed 2026-10-27↩
  6. docsFeatures and APIs overview | Android 12developer.android.comaccessed 2026-10-27↩
  7. docsAdd predictive backdeveloper.android.comaccessed 2026-10-27↩