Android task and process, SingleTask and SingleInstance

5.2k views Asked by At

I have read through Google Android Developer page, but the concept of task (http://developer.android.com/guide/components/tasks-and-back-stack.html) really confuse me.

After I read until SingleTask and SingleInstance, I am getting more confused.

I would like to ask some question by using examples, hope that I will have better understanding from these question:

Let's say I have 2 applications A and B, A has x, y, z activities; B has 1, 2, 3 activities:

Assume that their launch mode are Standard (Not using any intent flag). And x is Main Activity of app A; 1 is Main Activity of app B.

1) Launch app A, then x-> y -> 1, press home button, launch app A again, we will see activity y or 1?

2) Launch app A then x -> 1 -> y -> 2 -> z -> 3, press home button, launch app A, it will contain all the activities (x -> 1 -> y -> 2 -> z -> 3), or it contains x -> y -> z only? How about if we launch app B now? What activities will app B contain?

Now let's say activities 1, 2, 3 are SingleTask; x,y,z still Standard:

3) Launch app A, then x -> y -> 1 -> 2, press home button, launch app A, it will contain x -> y only or it contains x -> y -> 1 -> 2? How about if we launch app B now? app B will contain 1 only or 1 -> 2?

4) Launch app B, then 1 -> 2 -> 3 -> 1, will 2 and 3 be destroyed?

5) Launch app B, then 1 -> 2 -> 3, press home button, launch app A now, then x -> y -> 2 then press back button to drop 2. Launch app B now, what activities it contains? 1 -> 3 only or 1 -> 2 -> 3?

Thanks anyone reply and help!

1

There are 1 answers

3
David Wasser On BEST ANSWER

Assume that their launch mode are Standard (Not using any intent flag). And x is Main Activity of app A; 1 is Main Activity of app B.

1) Launch app A, then x-> y -> 1, press home button, launch app A again, we will see activity y or 1?

You will see activity 1. You have a single task that contains x->y->1 with activity 1 on the top of the activity stack in that task. When you press HOME, this task is moved to the background. When you launch the app again, Android finds the task stack and just brings it (intact) back to the foreground, showing you the top activity on the stack (in this case 1).

2) Launch app A then x -> 1 -> y -> 2 -> z -> 3, press home button, launch app A, it will contain all the activities (x -> 1 -> y -> 2 -> z -> 3), or it contains x -> y -> z only?

As above, you have a single task. When you press HOME, the task contains x->1->y->2->z->3 and is moved to the background. When you launch App A again, the task is brought forward (intact) and you will see activity 3 on top.

How about if we launch app B now? What activities will app B contain?

Well, the question as such is not correct. What you really want to know is "What activities will this task contain?", but here is the answer:

If you launch App B from the HOME screen, you will start a new task. This task will contain a single activity, namely 1. This task has nothing to do with the other task (which is still in the background). The fact that the background task contains activities from 2 different applications is irrelevant.

Now let's say activities 1, 2, 3 are SingleTask; x,y,z still Standard:

3) Launch app A, then x -> y -> 1 -> 2, press home button, launch app A, it will contain x -> y only or it contains x -> y -> 1 -> 2?

At the point where activity y launches activity 1, this will create a new task. So you will have one task containing activity x->y and a second task containing 1. When activity 1 launches activity 2 what happens depends on more than just the launchMode of the activities. Even if activity 2 is declared launchMode="singleTask", if the taskAffinity of activity 2 is the same as the taskAffinity of activity 1 (which, by default, it is, if they belong to the same application) then activity 2 will be created in the same task as activity 1 (ie: it will behave as if activity 2 had launchMode="standard"). However, if activity 1 and activity 2 have different taskAffinity, then activity 2 will be launched as the root activity in a new task. Now you will have 3 tasks, like this: Task1 contains x->y, Task2 contains 1 and Task3 contains 2.

How about if we launch app B now? app B will contain 1 only or 1 -> 2?

As above, this depends on taskAffinity. If the taskAffinity of activity 1 and 2 are the same, launching app B from the HOME screen will bring the task containing 1->2 to the foreground. If the taskAffinity of the activities is different, launching app B from the HOME screen will bring the task containing activity 1 to the foreground.

4) Launch app B, then 1 -> 2 -> 3 -> 1, will 2 and 3 be destroyed?

No. 2 and 3 will not be destroyed. Assuming that 1, 2 and 3 all have launchMode="singleTask" then it (again) depends on the taskAffinity settings. Assuming all activities have the same taskAffinity, then you will have a single task containing 1->2->3->1 (you will have 2 instances of activity 1) because taskAffinity trumps launchMode.

If all activities has different taskAffinity, then after 1->2->3 you will have 3 separate tasks, each containing a single activity. Then, when activity 3 starts activity 1, this will just bring the task containing activity 1 to the foreground and will not create a new instance of activity 1.

5) Launch app B, then 1 -> 2 -> 3, press home button, launch app A now, then x -> y -> 2 then press back button to drop 2. Launch app B now, what activities it contains? 1 -> 3 only or 1 -> 2 -> 3?

Again, this depends on taskAffinity. If all activities of app B have the same taskAffinity then after 1->2->3 you will have one task. User presses the HOME button this task will go to the background. Now user launches app A creating a new task. After x->y the second task contains these 2 activities. Now activity y starts activity 2. Since this activity has launchMode="singleTask" and has a different taskAffinity from the other activities in the task (they all have taskAffinity of App A), Android will create a new task with activity 2 as the root. Android cannot use the existing task containing 1->2->3 because that task does not contain activity 2 as its root. When the user presses BACK in 2, this will finish activity 2 which will finish the third task, returning the user to the second task containing x->y with activity y on top. Now pressing HOME and launching app B will bring the existing first task containing 1->2->3 to the foreground.

However, if all the activities of app B have different taskAffinity, then after 1->2->3 you will have 3 separate tasks each containing a single activity. User presses HOME and launches App A creating a new task (now you have 4 tasks). After x->y the fourth task contains these 2 activities. Now activity y starts activity 2. Android simply brings the task containing activity 2 to the foreground. User presses the BACK button, this finishes activity 2 and the task it was in (because that task is now empty), returning the user to the previous task which is the one containing x->y from app A. Launching App B from the HOME screen will simply bring the task containing activity 1 to the foreground. You now have 3 tasks: Task1 contains activity 1 and is in the foreground, Task2 contains activity 3 and is in the background, Task3 contains x->y and is in the background.

NOTES

I realize this is complicated. My answer is from my head, I have not attempted to actually implement all these combinations and check (however, I have implemented many of these cases in the past and I do know how it really works). The reason is that most of what you described would not be done in the real world, so the examples are only theoretical and not practical. In real life you hardly ever need to use the singleTask or singleInstance launch modes unless you are building your own HOME-screen replacement or you need to carefully control the way your application behaves when it is started by other applications. In most cases you will never have more than one activity which has a launch mode of singleTask or singleInstance.

If you use singleInstance or singleTask you need to be aware of how taskAffinity works and you also need to make sure that you have a different app icon (and probably also app label) for each activity that is declared as 'singleTask' or 'singleInstance'. If not, the user will not be able to return to the correct task due to the way these are shown in the list of recent tasks.