Understanding android Activity and Its Launch Modes Standard, singleTop, singleTask, and singleInstance (with examples)
Activities are the fundamental building blocks of Android apps, and launch modes are attributes that we can use to change default stacking behavior. It may sound like a difficult programming concept, but it is not and here I will explain activities and their launch modes the easy way.
An activity is a screen shown in response to a user's action. For example, when you touch an app icon and it launches a screen, this first screen is the first activity. Technically speaking, an activity implements a part of the application’s visual user interface.
An activity can have four states and we will discuss them briefly here.
Activity is in an active state when it has the focus and it is ready to receive input from the user. The input can be in any form, most often a tap of a link or a button.
When a user interacts with an activity or a screen, it usually causes a new activity to start and the system transfers the focus, or intent, to the new activity leaving the previous one inactive. An inactive activity is still there but in an inactive state. An inactive activity can receive focus and become active again.
An activity is destroyed when a user presses the back button. This action destroys the active activity and passes the focus to the previous one. Once an activity is destroyed, it must be created again; there is no way to bring a destroyed activity to life.
An activity can remain active even when it is not visible to the user. This activity state is useful in certain multitasking scenarios.
A task is a collection of activities. Because activities are placed, or stacked, on top of each other, it is often called a stack. A stack of activities has a specific order and new tasks are added to the top giving it its famous name: back stack. So, when you read these nerdy-looking terms, remember that they all refer to a task, which is a container for activities.
All activities must be represented by the
The way activities are placed in a task can best be explained by my favorite fruit shop example. Imagine we have made an app to view beautiful pictures of our favorite fruits; we will leave the buy functionality for later, however.
When we tap the app’s icon, the tapping action starts an activity, which results in displaying the homepage of our fruit shop. This is the first activity, also known as the root activity, and it is placed in a new container we know as a task. For our programming purposes, we will name this activity 01-Homepage. When we click on that delicious apricot thumbnail on our app’s homepage, a new activity named 02-Apricot starts resulting in a screen filled with big mouth-watering pictures of apricots. This second task is placed on the top of the 01-Homepage. Please note that 01-Homepage is still there, but it is in an inactive state while the 02-Apricot has the focus and is in an active state.
We can go further and explore a specific type of apricot known as Castlebrite, which will cause a new activity 03-ApricotCastlebrite to be placed in the same task on the top of the other activities. The top activity has the focus while the other two remain laying in the stack in an inactive state.
We have created a few activities above. Let’s destroy some for the fun of it. To destroy an activity, we only need to press the back button. When we press the back button and move from 03-ApricotCastlebrite to 02-Apricot, the third task is not preserved but destroyed. Now if you want to know more about Castlebrite Apricots, you will tap the corresponding button and a new 03-ApricotCastlebrite task will be created on the top of the stack in the same task.
Wondering why the system must destroy the third task and why we must create a new task at all? Well, this is how activities behave in their default mode. Fortunately, however, we can change this default behavior by flags in the intent or by adding attributes in the
Do not use launchMode just for the sake of using it. Using launchMode unnecessarily can cause serious performance and functional issues. But feel free to use launchMode to achieve something not possible with the default behavior. Remember to test your app before marking it as done.
Let’s examine a scenario where modifying the default behavior on our Android app is desirable. With respect to our Fruit Shop example, we have noticed that when we are on the 03-ApricotCastlebrite and close the application, it freezes all three tasks but does not destroy them. And when we open the app again or access it through the Recent Apps screen, the app resumes from 03-ApricotCastlebrite, but we do not want this behavior. It would be a better user experience if the user does not need to press Android’s back button many times to go to the homepage to see fruits other than apricots, and we want our app to show 01-Homepage after every relaunch. This is where we use launchMode attribute to achieve the desired behavior.
There are four launch modes
For easy understanding, we will examine it in pairs, with the first pair consisting of standard and singleTop.
We have already discussed the standard, or the default, activity launch mode. In this mode, each new activity is placed on the top of the stack, and whenever the user presses the back button, the topmost activity is the first to go.
As the last activity is destroyed first, we can say that the last activity in the task is the first to go out or LIFO (last in, first out), a term commonly used in accounting.
One thing we have not discussed previously, however, is how standard mode handles duplicates. In the standard mode, the system always creates a new instance of the activity even if the activity already exists in the stack.
Figure 1: a task containing three activities with the first activity at the bottom and the third on the top
singleTop launch mode is similar to the standard with only one difference. If a user performs an action that requires the initiation of a new activity, the system will check the existing stack for the presence of the same activity. If the activity already exists in the stack AND is on the top, it will pass on the focus to this activity rather than creating a duplicate activity on the top. More precisely, we can say that system routes the intent to the existing instance instead of creating a new instance of the activity.
To sum up the behavior of our first launchMode pair, the standard mode always creates a new instance of the activity even if the same instance is already present in the task. On the other hand, singleTop launch mode checks the existence of the required activity, and if it finds that the required activity already exists in the stack and is currently on the top, it passes intent to that activity. Let’s examine our second launchMode pair.
launchMode does not rearrange the activities in the stack
In the previous launchMode pair we examined, both standard and singleTop create new activities on the top of the same stack in the same task. There are scenarios, however, where we might want to start a new task altogether. When we use singletTask launchMode, the system checks if the activity already exists in the stack, and if it does, the system routes the intent data to the activity onNewIntent() Method. If the required activity does not exist, however, it creates a new task and places the newly created activity at the top of the activity stack, and clear all other activities present above it. This is in contrast to both launch modes in the first pair that created activities in the existing task only.
Let's assume we have 4 Different activities in a stack A, B (B Activity has LaunchMode singeTask), C, and D, and the order of the activities is like
A->B->C->D (Activity D at the top of the stack) and there in Activity D we create A new intent to start Activity B after Launching singleTask Activity B activities stack will look like this.
system will clear out all the activities (Activity C & D) above activity B and intent data will route through activity onNewIntent() method
And now here if you launch B Activity Again this time state of activity stack will remain the same (A->B) and activity onNewIntent Method will call
Note: singleTask activity will behave the same as a standard activity when you will launch it for the first time.
We noticed that singletTask is used to create a new task for the new activity. However, once the system has created a new task and placed the newly created activity in it, new activities can be created in this task. singleInstance, however, forces any new activities to have their own task with a result that there is only one activity in any given task. There cannot be more than one activity in a task because every time an activity is created with singleInstance, it automatically creates a new task for the activity.
Let's suppose we have Activity A,B, C and D And Activity D has Launch Mode singleInstance now we have launched 3 Activities A,B, and C after that state of activities stack would like this Activity A --> B ---> C and after launching singleInstance Activity D state of activity stack would like this
Task1 = A->B->C
Task2= D (Activity D will Launch in the new task)
now if you will lunch activity D again System will first check Activity D instance is present, if it does, intent data will route through onNewIntent() acidity method.
Note: if you want to check different tasks you should use taskAffinity attribute with singleInstance
<activity android:name=".MainActivity" android:launchMode="singleInstance" android:taskAffinity="com.some.affinity" />
That’s how we can manipulate activities and tasks using launchMode to fit our Android app-building needs. As a reminder, only use launchMode when it is required, and remember to test the app thoroughly to be sure that it works as expected.
Have a question or comment? Please feel free to post in the comments, and I will do my best to answer your questions.