Kahibaro
Discord Login Register

11.3 Activity Back Stack

Understanding the Activity Back Stack

The activity back stack is how Android remembers which screens the user has visited and what should happen when they press the system Back button. It is like a stack of cards, where each card is an Activity. When the user opens a new screen, a new card is added. When they go back, the top card is removed and the one below becomes visible.

This chapter focuses on how the back stack works for activities, how it affects navigation, and which tools you have to control it. It assumes you already know how to start activities and pass data using intents.

The Stack Model of Activities

Android manages activities in a stack. The first activity in your app that the user sees is usually called the "launcher activity". When this activity starts, it becomes the bottom element of the stack. If the user navigates to another activity, this new activity is placed on top of the stack.

At any time, only the activity at the top of the stack is in the foreground and interacts with the user. The activities below it are kept in the background and may be destroyed when the system needs memory, but their position and navigation order are still remembered.

When the user presses the system Back button, Android typically destroys the current top activity and returns to the previous one in the stack. If there is no previous activity inside your app, pressing Back usually closes your app and returns the user to the home screen or to the previous app.

Important:
The activity back stack is last in, first out. The last started activity is the first one to be removed when the user presses Back.

Default Behavior When Navigating

When you call startActivity(intent) from one activity to open another, Android does the following by default. It creates the new activity instance, puts it on top of the current task's back stack, and shows it to the user. The previous activity remains in the stack below and is moved to the background.

For example, if the user flows through activities like this:

  1. MainActivity is opened from the launcher.
  2. DetailsActivity is started from MainActivity.
  3. SettingsActivity is started from DetailsActivity.

The stack from bottom to top will be:

MainActivity → DetailsActivity → SettingsActivity

If the user now presses Back, the following happens in order. SettingsActivity is destroyed and removed from the stack. DetailsActivity becomes visible again. Pressing Back again destroys DetailsActivity and returns to MainActivity. Another Back press from MainActivity will usually close the app.

You do not need extra code for this default behavior. It is provided automatically as long as you start activities with startActivity.

Tasks and the Back Stack

A "task" in Android is a collection of activities that the user has interacted with, arranged in a back stack. When you open an app from the launcher, Android typically creates a new task for that app and places the launcher activity as the root of that stack.

All subsequent activities that your app starts by default run in the same task and share the same back stack. When the user leaves your app using the Home button, the task is moved to the background but the stack is preserved. Later, when the user selects the app from the recent apps screen, the task and its entire back stack are brought back to the foreground.

It is possible for advanced use cases to work with multiple tasks or to place activities in different tasks, but for most beginner apps you usually have a single task that contains your app's activities.

Overriding the Back Button

Although the system Back button automatically navigates the back stack, you can override this behavior inside your activity when you need custom logic. Android calls the onBackPressed() method (or in newer APIs, OnBackPressedDispatcher) when the user presses Back while your activity is on top.

In an activity using the older approach, the method looks like this:

override fun onBackPressed() {
    // Custom behavior before back navigation
    // For example, close a dialog or show a confirmation
    // Call super to perform the default back stack behavior
    super.onBackPressed()
}

If you do not call super.onBackPressed(), the activity will not be popped from the back stack automatically. You can choose to finish the activity manually with finish(), or decide not to exit at all, depending on your needs.

On newer projects, you often use onBackPressedDispatcher with callbacks, especially when working with fragments or custom navigation. Even in that case, the concept is the same: you can intercept the back action, perform some logic, and then let the stack be updated or keep the user on the same screen.

Rule:
If you override back behavior, always make navigation predictable and consistent. Unexpected back actions confuse users and make your app feel broken.

Finishing Activities and Controlling the Stack

Sometimes you want to remove an activity from the back stack as soon as the user leaves it, instead of letting it remain below the next one. For example, after a login screen, you might not want the user to press Back and return to the login activity once they are logged in.

To manually remove the current activity from the stack, you call finish() in the activity. This method closes the activity and removes it from the back stack. You might call finish() right after starting a new activity.

For example:

val intent = Intent(this, HomeActivity::class.java)
startActivity(intent)
finish()  // Remove the current activity so Back will not return here

When finish() is called, the activity will go through its destruction lifecycle, and the previous activity in the stack will become the top activity. If there is no previous activity, the task will end.

You can also finish an activity in response to some event, like the user completing a form or clicking a "Done" button. This gives you explicit control over which screens remain in the navigation history.

Launch Modes and Back Stack Behavior

Android provides launch modes that influence how activities are added to or reused from the back stack. These are configured in the manifest or at runtime with intent flags. They are more advanced tools, but it is useful to understand their basic effect on the back stack.

One common setting is singleTop. When an activity uses singleTop, if an instance of that activity is already at the top of the back stack and you try to start it again, Android does not create a new instance. Instead, it reuses the existing one and calls onNewIntent() on it. This prevents duplicate instances of the same screen being stacked on top of each other.

Another mode is singleTask. With this mode, there can be only one instance of the activity in the task. If the activity already exists somewhere in the back stack, Android brings it to the top and removes all activities that were above it.

There are also intent flags that affect how the back stack is handled. For example, you can use FLAG_ACTIVITY_CLEAR_TOP with an intent to clear activities above a certain one when you navigate back to it.

Here is a simple example using FLAG_ACTIVITY_CLEAR_TOP:

val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(intent)

If MainActivity already exists in the stack, this call will remove every activity on top of MainActivity and bring it to the front instead of creating a new instance. This can be useful when you want to return to a "home" activity and clear intermediate screens.

Important:
Launch modes and flags change how activities interact with the back stack. Use them only when you clearly understand the navigation pattern you want to achieve.

System Behavior and Back Stack Clearing

Android can remove activities from the back stack when the system needs memory. If your activities are in the background, they may be destroyed. However, the logical order of the stack is preserved. When the user navigates back to a destroyed activity, Android recreates it and calls its lifecycle methods as if it is being created again.

This is why you must always save important UI state and data. Even though the back stack remembers the order of activities, it does not guarantee that your activity instances stay alive. You handle state through lifecycle methods, saved instance state, and other storage mechanisms that are described in other chapters.

In some situations, you may also want to clear the entire task. For example, when the user logs out, you might want to clear all previous activity history so Back does not return to protected screens. One common pattern is to start a new activity with a fresh task and clear the old one using intent flags like FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_CLEAR_TASK. The exact combinations and detailed behavior of these flags are more advanced topics, but the effect is that the previous back stack is removed.

Designing Intuitive Back Navigation

A well designed back stack feels invisible to the user. They press Back and naturally move through the screens they visited, or exit the app when they expect to. Problems appear when you break this mental model by blocking back unexpectedly, jumping to random screens, or reordering activities in confusing ways.

When designing your navigation, think in sequences. If the user flows from A to B to C, pressing Back should usually return them from C to B to A. If you need a different behavior, like skipping a login screen, adjust the back stack deliberately, for example by calling finish() after launching the next activity.

You should also consider the difference between the system Back button and other navigation controls like toolbar "Up" buttons or bottom navigation. The system Back always moves through the back stack, while "Up" navigation often follows your app's hierarchy. A clear understanding of your back stack helps you keep both behaviors consistent.

By thinking of activities as elements in a stack, using startActivity to add them, finish() to remove them, and only applying launch modes or flags when necessary, you gain precise control over how your users navigate through your app.

Views: 2

Comments

Please login to add a comment.

Don't have an account? Register now!