Activity launch modes: Android

Gaurav Rajput
7 min readJan 3, 2021

--

To understand launch modes, lets first understand

What is Task?

What is back stack?

What is task-Affinity?

Task means stack of activities. Stack basically works on last in first out the concept, so the activity that is at the top of the stack ( which comes last ) will be poped ( out of stack) first. In the Android system, as you start an activity, it goes into a stack . And when you press the back button, this activity is popped from the stack given in the below image.

This stack is called Back Stack here.

Here let's assume Activity 1 is starting Activity 2 , so Activity 1 will be stopped and Activity 2 will start. But as soon as you press back button Activity 2 will be destroyed and Activity 1 resumes.

But how androids restoreActivity 1 ?

The Android system retains its state (such as scroll position and text entered into forms, etc.) and resumes it from there.

Another question :

What will happen with this stack if the user presses the home button?

The answer is, as soon as the user presses the home button, the current activity will be stopped, and this whole task (let's say Task A) will be in the background, and all activities state are saved that are in Task A.

What will happen if the user relaunches the app by clicking on the launcher icon?

Firstly this task will come in the foreground, and it will resume the activity at the top of the stack.

What will happen if the user launches the other app by clicking on the launcher icon?

The current task ( Task A) will be in the background, but a new task (let's say Task B) will be created for this new app. And it will start pushing the activity (as activity starts ) into this new task or back stack. Older task ( Task A) will be in the background. If the user clicks on the first app (having Task A as a back stack), thenTask A will be foreground and Task B will move to the background.

Task Affinity

The affinity indicates in which task, activity refers to belongs to. By default, all activity belongs to the same task. But it can be modified using taskAffinity an attribute of the <activity> element. This attribute takes a string value (unique from the package name declared in the manifest element). The reason for this unique value is that the android system uses that name to identify the default task affinity for the app ( package name defines the default task affinity).

As an example :

<activity android:name=".ActivityD"
android:launchMode="singleTask"
android:taskAffinity="com.affinity.of.a"/>
<activity android:name=".ActivityC"
android:taskAffinity="com.affinity.of.c"
android:launchMode="singleTask"/>
<activity android:name=".ActivityB"
android:taskAffinity="com.affinity.of.b"
android:launchMode="singleTask"/>
<activity android:name=".ActivityA"
android:taskAffinity="com.affinity.of.a"
android:launchMode="singleTask"/>

Here we can see ActivityD and ActivityA have the same affinity. Both will belong to the same task.

We will see the use of this attribute in the case of SingleInstance and SingleTask launch mode.

We have four types of activity launch modes available in the android system :

  1. Standard
  2. Single Top
  3. Single Task
  4. Single Instance

Standard launch mode

This is the default one; every time you launch an activity with this launch mode, it will create a new instance of activity and will be moved to the stack.

Let's see by example:

Example 1: let's launch the activity A ,Activity B and Activity C in sequence.

Stack will be (bottom) A => B=> C (top) C will be at the top; let’s call it Task 1 for future reference.

Task 1: (bottom) A => B=> C (top)

Now let's suppose we launch Activity C with standard launch mode.

In this case, a new instance of C will be moved to that task . The final result will be :

A => B =>C =>C (new instance)

Single Top launch mode

If we launch an activity with a single top launch mode, it will check whether it has the same activity at the top of the stack. If the same activity is at the top, no new instance will be created; if it's not at the top, a new instance will be created.

In example 1, what will happen if we want to launch C with singleTop launch mode?

The existing instance of C receives the intent via onNewIntent(), because it's at the top of the stack—the stack remains A =>B=>C. Here no new instance will be created.

What will happen if we want to launch B with singleTop launch mode in this case?

A new instance of B will be created as we don't have B at the top of stack and stack will be A=>B=>C=>B.

Single Task launch mode

In this case, a new task will be created, and a new instance of activity will be moved at the top of the new stack (if this new activity have different taskAffinity). We have two scenarios here :

  1. What if we don't have any instance of this activity in a stack?

In this case, we have two conditions :

First, if the activity has a different taskAffinity for this newly created activity?

In this case, a new task will be created, and a new instance will be created and moved at the top of this new stack.

In example 1, if we launch the Activity D a new task will be created and D will be moved to it like below:

First Stack:=> (bottom) A => B=> C (top)

Second Stack => D

Second, if the activity has the same taskAffinity as activities in the first Task or first Stack?

In example 1, if we launch the Activity D , no new task will be created. There will be only one task:

(bottom) A => B=> C => D (top)

2. What if we already have one instance of this activity in the different stack?

Let's suppose in the above example we want to launch Activity B . No new instance will be created; the system routes the intent to this instance (instance of First Stack) via a call to its onNewIntent() method, rather than creating a new instance.

The final result will be :

First Stack:=> (bottom) A => B (top)

Here Activity C will be destroyed in this case. Only one instance of the activity can exist at a time.

Let's understand the same concept using the below image.

Here let's assume we have a Background task which have Activity X , Activity Y and current stack having two activities Activity 1 and Activity 2 . Now we want to launch Activity Y , now the back stack includes all activities from the background task, brought forward, at the top of the stack and resumes Activity Y now if the user presses the Back button Activity 2 won't be resumed instead of that Activity X will be resumed if the user again press back button then only Activity 2 will resume.

Single Instance launch mode

Single Instance works similarly as Single task the only difference is it doesn’t launch any other activities into the task holding the instance. Basically, it will contain a single instance of the activity in a task; any activities started by this one open in a separate task.

We have two cases here :

  1. What if we don’t have any instance of this activity in the different stack?

In this case, we have two conditions :

First, if the activity has a different taskAffinity for this newly created activity?

In this case, a new task will be created, and a new instance of activity will be created and moved at the top of this new stack.

In example 1, if we launch Activity D with singleInstance launch mode, a new task will be created and D will be moved to it like below:

First Stack:=> (bottom) A => B=> C (top)

Second Stack => D

What if we want to launch activity E with singleInstance?

i) with task affinity of same as of D -

In this case, it will remove D from the second stack and E will be moved to the second stack. The final result will be

First Stack:=> (bottom) A => B=> C (top)

Second Stack => E

i) with task affinity of same as of first task ( which have A, B and C) -

In this case A, B and C will be removed from the first stack and E will be pushed into the first Stack. The final result will be:

First Stack:=> (bottom) E (top)

Second Stack => D

Second, if the activity has the same taskAffinity for this newly created activity?

Let's suppose we have three activity A, B and C right now and the stack is like below:

(bottom) A => B=> C (top)

If we launch the Activity D .

In this case, A, B and C will be removed from the first stack and D will be pushed into the first Stack. The final result will be:

First Stack:=> (bottom) D(top)

2. What if we have an instance of this activity in a stack?

Let's suppose in the above example we want to launch Activity D. No new instance will be created; the system routes the intent to this instance ( instance of First Stack) through a call to its onNewIntent() method, rather than creating a new instance.

The final result will be :

First Stack:=> (bottom) A => B (top)

Second Stack => D

P.S.- If you have any doubt or confusion please leave a comment. You can find a small projects to understand it here : https://github.com/02gaurav/activity-launch-modes.git

--

--