launchMode="singleTask" does not create a new task
Asked Answered
M

2

8

I have 2 activities: Activity A and Activity B. Activity A's launch mode is standard, and Activity B's launch mode is singleTask.

 <activity
    android:name=".AActivity"
    android:label="@string/app_name"
    android:launchMode="standard">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="dd"></data>
        <data android:host="a"></data>
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
</activity>
<activity
    android:name=".BActivity"
    android:label="@string/app_name"
    android:launchMode="singleTask">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="dd"></data>
        <data android:host="b"></data>
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
</activity>

I launch the app, and the launcher Activity A starts. Then i press Home Button and return to home screen of the phone. Then i launch browser app and type the following:

dd://b

to open Activity B. The system navigates to my App and starts activity B on top of activity A. At this point if i press back button, activity B is popped and i see activity A.

This is not what i expected because the android documentation states:

For singleTask activities, the system creates a new task and instantiates the activity at the root of the new task. However, if an instance of the activity already exists in a separate task, the system routes the intent to the existing instance through a call to its onNewIntent() method, rather than creating a new instance. Only one instance of the activity can exist at a time.

What i understand from these sentences is, in my case since an instance of Activity B does not exist, a new task should have been launched and it should have had only Activity B at its stack(Another instance of my app should still exist in a separate task and it should have Activity A in its stack). Then if i press back while i was at Activity B, since it is the only activity in the backstack, it is popped out and the system returns to the browser.

Why this is not the case? How does android system know that my app is open and navigates to it and starts activity B on top of existing app stack instead of launching another instance of my app and letting two instances of my app have their own stacks? What does it mean to instantiate activity in a new task? Can anyone explain?

Thanks.

Movable answered 28/9, 2015 at 13:19 Comment(0)
M
8

In addition to the accepted answer, I found an explanation to this problem. As android documentation states:

The affinity indicates which task an activity prefers to belong to. By default, all the activities from the same application have an affinity for each other. So, by default, all activities in the same application prefer to be in the same task which belongs to that app(The app that has the Activity B). However, you can modify the default affinity for an activity.

So, if your app is running, and you start an activity, which has launchMode:singleTask attribute, unless you explicitly state taskAffinity attribute, it starts the activity in the same task. But if you explicitly state an affinity in your manifest:

<activity
        android:name=".BActivity"
        android:label="@string/app_name"
        android:taskAffinity=""
        android:launchMode="singleTask">
</activity>

then it starts the activity in a new task.

You can see which activity belongs to which task by the following adb command:

adb shell dumpsys activity

and also, to better understand launchMode concept, you can see the following app in the Google Play: https://play.google.com/store/apps/details?id=com.novoda.demos.activitylaunchmode

Movable answered 28/9, 2015 at 19:43 Comment(2)
this explains it further. Nice find.Lofty
The android documentation states that "singleTask : The system creates a new task and instantiates the activity at the root of the new task". And then adds "Regardless of whether an activity starts in a new task or in the same task as the activity that started it, the Back button always takes the user to the previous activity. So how can you be so sure "singleTask" doesnt start a new task by default? developer.android.com/guide/components/activities/…Typewriting
T
0

You said that your app navigate to B in passing by A.

So, i think you have two stack. In the first, you have only A, in the second you have only B. If you press back, then B is popped and disapeared but A exists and is showing because A in behind B even if A and B are in separate stack.

If you want that B pop and then you return to home, try to call "finish()" after call B from A

Tartarus answered 28/9, 2015 at 13:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.