Why Behaviours are different ?- android:launchMode="singleTask" , android:taskAffinity="" And Intent.FLAG_ACTIVITY_NEW_TASK
Asked Answered
B

2

6

I have Four Activity - A,B,C,D

I am calling these four activity in manner --> A-B-C-D-B. (Specified Manner)

I have three scenario.

1st :- I am defining android:launchMode="singleTask" only in B Activity. And I am calling all activity via Intent in above specified manner.

Now First calling A-B-C-D , BackStack Task 1 : A-B-C-D,

Now I again call B, Then BackStack Task 1 : A-B. Here C and D Activities are destroyed.

2nd :- I am defining android:launchMode="singleTask" & android:taskAffinity="" in B Activity. And I am calling all activity via Intent in above specified manner.

Now First calling A-B-C-D , BackStack Task 1 : A

                                  Task 2 : B-C-D

Now I again call B, Then BackStack Task 1 : A

                                Task 2 : B ,Here C and D Activities are destroyed.

3rd :- I am defining Intent.FLAG_ACTIVITY_NEW_TASK & android:taskAffinity="" in B Activity. And I am calling all activity via Intent in above specified manner.

Now First calling A-B-C-D , BackStack Task 1 : A

                                  Task 2 : B-C-D

Now I again call B, Then BackStack Task 1 : A

                                Task 2 : B-C-D , Here **Can't call B again**

And here It says FLAG_ACTIVITY_NEW_TASK produces the same behavior as the "singleTask" - https://developer.android.com/guide/components/activities/tasks-and-back-stack.html

So Which are correct scenarios? I am getting it right or I am misunderstanding something.

Burgeon answered 26/9, 2017 at 13:23 Comment(11)
Have you used onNewIntent() in the activities with singleTask launchMode ?Typewriting
No, I have not used it. what will be syntax of it? I mean onNewIntent()'s syntaxBurgeon
check this out: https://mcmap.net/q/369627/-how-to-capture-the-new-intent-in-onnewintentTypewriting
But , I am not passing any values between Activities , So Should I compulsorily override onNewIntent() method?Burgeon
And on primary stage, I want to know correct behavior of above scenario, Are those correct or not?Burgeon
Where are you launching the activities from? Does A launch B and then B launches C and then C launches D and then D launches B?Mastodon
@Typewriting the usage of onNewIntent() is totally irrelevant to this question.Mastodon
@David Wasser, Yes, A is lauching B, B is to C, C is to D , and D to B via Intent on Button click.Burgeon
Also, what device (or emulator) are you testing on and what version of Android is it running?Mastodon
@David Wasser, I m running on MI note 4 device and Android version is 7.0Burgeon
I need to do a bit of testing. I'll come back to you soon.Mastodon
M
8

I've reproduced the behaviour as you've described.

The first scenario is basically undocumented because a singleTask Activity should always be the root of a task. Because Android uses taskAffinity when determining how and where to launch an Activity, your singleTask Activity is being launched into the existing task, but not as the root Activity. This makes the behaviour different from the behaviour that is documented. When you launch B from D, Android needs to deliver the Intent to B in a call to onNewIntent(), which it cannot do with C and D sitting on top of B. So Android finishes C and D and then calls onNewIntent() on B.

The second scenario shows that you now have 2 tasks, because the singleTask Activity is launched into a new task as the root Activity. Again, when D launches B, Android needs to deliver the Intent to B by calling onNewIntent(), which it cannot do if C and D are in the way. So Android finishes C and D and then delivers the Intent to B in onNewIntent().

The third scenario shows the use of FLAG_ACTIVITY_NEW_TASK. When A launches B with FLAG_ACTIVITY_NEW_TASK, Android looks for an existing task that has B as the root Activity. Since it doesn't find one, it launches B in a new task as the root Activity. When D launches B with FLAG_ACTIVITY_NEW_TASK, Android looks for a task that has B as the root Activity, and if it finds one, it brings that task to the foreground but does not deliver the Intent to onNewIntent(). This is just a way to bring an existing task to the foreground in the state that it was in when it went to the background. This is what you are seeing. This behaviour is also documented (sort-of), but due to the very complex interdependencies between all of these scenarios, all possible cases are not explicitly documented. Sometimes you need to discover how this works by empirical observation instead of reading the documentation.

Thanks for the challenge.

Mastodon answered 29/9, 2017 at 11:37 Comment(3)
David Wasser,Thank you for Detailed response. It is very useful. But I have one question. As you explained Third scenario, >When D launches B with FLAG_ACTIVITY_NEW_TASK, Android looks for a task that has B as the root Activity, and if it finds one, it brings that task to the foreground but does not deliver the Intent to onNewIntent(). >But in my case, When I call B again after D, I can't seem to call again. It is not changing to Activity B. It is stuck to Activity D.Why is it happening?Burgeon
In the 3rd scenario, Android brings the task to the foreground. The task has B at the root, but D is the topmost Activity, so it is the one that is showing. If you really want to bring B to the top (so that it will be on display), you either need to use Intent.FLAG_ACTIVITY_REORDER_TO_FRONT (which will put B on top of D) or use Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP which will finish D and C and show the existing instance of B, or just Intent.FLAG_ACTIVITY_CLEAR_TOP which will finish D, C and B, then launch a new instance of B.Mastodon
So, In conclusion, Intent.FLAG_ACTIVITY_NEW_TASK(only single attribute) will not work as a 'singleTask'. Thank you. It works fine now as you described :-)Burgeon
K
0

As a supplement to the above answer, now I'm using pixel 2 with API 29, the results of scenario 1 and 2 remain the same, but in scenario 3 a new instance of B will be added to task stack instead of just bringing the task to the foreground.

Unfortunately, this behavior is still poorly documented.

Kathaleenkatharevusa answered 15/7, 2022 at 6:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.