As usual (sigh), the documentation is wrong. In the diagram you referenced, obviously Activity Y can't be defined as singleTask
and yet be the top activity in a background task containing 2 activities.
When testing scenarios with special launch modes singleTask
and singleInstance
, please be aware that taskAffinity
plays an important role in this behaviour, as taskAffinity
takes priority over special launch modes.
Regarding the difference between "task" and "back stack":
A "task" is a stack of activities that can be manipulated as a whole group.
- When you launch an application (assuming that it isn't currently running), Android creates a new task which is in the foreground and contains the root activity of the application you launched.
- When that activity starts new activities, these new activities are added to current task (usually, although there are exceptions to this behaviour).
- When you press the HOME button, the current task is moved from the foreground to the background.
- When you show the list of "recents", what is displayed is the list of recent tasks, not the list of recent activities or list of recent applications.
- When you select a task from the list of recent tasks, if that task is still active (still has live activities in it), the entire task (including all of its activities) will be brought from the background to the foreground.
- Tasks can also be "stacked". When an activity in the current task starts an activity in a new task, the new task is stacked on top of the current task. This only serves to control what happens when the new task completes. In the usual case, when the new task completes (all of its activities have finished), Android will return the user to the previous task (ie: the task that started the completing task).
A "back stack" usually refers to a set of activities within a task. Each task has its own stack of activities. This is used to control what happens when the current activity (the one on top of the back stack) finishes. Normally Android returns the user to the activity that is directly underneath (below) the finishing activity in the back stack.
The Android code and documentation often refer to the "root" of a task (this is the activity that was used to start the task) and the "top" or "front" of a task (this is the activity that is currently being shown).
Actually, the documentation lies :-( Here's an example:
In contrast, "singleTask" and "singleInstance" activities can only
begin a task.
This statement is usually, but not always correct. For example, let's say I have 2 activities: A
and B
. A
is the launch activity (ie: the one with ACTION=MAIN
and CATEGORY=DEFAULT
) and is defined with standard launch mode. B
is defined with launchMode="singleTask"
. I start the application and Android creates an instance of A
. In A
I then do:
startActivity(new Intent(this, B.class));
This will create a new instance of activity B
and put it on top of A
in the same task. It will not create a new task with activity B
as the root. The reason is that activity A
and activity B
have the same taskAffinity
(by default all activities of an application have the same taskAffinity
), and Android will ignore the launch mode of B
in this case.
The documentation also says:
Moreover, the device can hold only one instance of the activity at a
time — only one such task.
Again, taskAffinity
can break this behaviour. Assume again we have A
, B
and C
, all with the same (default) taskAffinity
. A
and C
have standard launch mode, B
has launchMode="singleTask"
. If A
starts B
, the instance of B
ends up not in a new task, but in the same task as A
(see above). Now B
starts C
. Android creates an instance of C
and puts it on top of B
in the same task. Now C
calls:
startActivity(new Intent(this, B.class));
Android creates a new instance of B
and puts this on top of C
in the task. There are now 2 instances of B
and neither of them is the root activity of the task! This behaviour is also due to the fact that taskAffinity
trumps launch mode.