3

Could please someone give me an example of how we can create a task back stack with having an Activity, which has launchMode=singleTask, at top of the stack and it's not the only activity in the back stack.

For example, we have one such task in the below diagram (the one including Activity X & Y);

enter image description here

As far as I know, singleTask activity is supposed to be the root one and task elements can never be rearranged.

Thanks in advance

stdout
  • 2,471
  • 2
  • 31
  • 40

2 Answers2

0
  1. Create an app Application1 with four Activities:
    • Activity1
      • Make sure that it is not exported="false" (that is, it's true either explicitly or implicitly)
      • Make it the launcher
    • Activity2
    • ActivityX
    • ActivityY
      • It's the one: launchMode="singleTask"
  2. In Activity1 implement two actions, e.g. two distinct buttons each doing the following:
    • Start Activity2 and finish itself
    • Start Activity2 and do not finish itself
  3. In Activity2 implement two actions:
    • Start ActivityX and finish itself
    • Start ActivityY and do not finish itself
  4. In ActivityX implement one action:
    • Start ActivityY and do not finish itself
  5. ActivityY do nothing :)
  6. Create another app Application2 with an Activity:
    • AnotherActivity
      • Make it the launcher
  7. In AnotherActivity implement one action:
    • Start Activity1. You can do it like this:
        Intent intent = new Intent();
        // package, fully qualified class name
        intent.setComponent(new ComponentName(
            "com.stackoverflow", "com.stackoverflow.Activity1");
        startActivity(intent);
  1. Launch Application1, which will start Activity1
  2. In Activity1, start Activity2 finishing itself
  3. In Activity2, start ActivityX finishing itself
  4. In ActivityX, start ActivityY
  5. Press home
  6. Launch Application2, which will start AnotherActivity
  7. In AnotherActivity, start Activity1
  8. In Activity1, start Activity2 without finishing itself
  9. In Activity2, start ActivityY without finishing itself

There you go. Pop the stack with the back button now.

nandsito
  • 3,782
  • 2
  • 19
  • 26
0

Actually, this is pretty easy to do.

To generate a task that contains X at the root and Y on top, even though Y is declared with launchMode="singleTask":

<application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
    <activity android:name=".X">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
    <activity android:name=".Y" android:launchMode="singleTask"/>
</application>

In activity X just launch activity Y like this:

startActivity(new Intent(this, SingleTaskActivity.class));

You will now have a task with activity X at the root and activity Y on top of that.

This happens even if you explicitly say that you want Y launched in a new task, like this:

Intent intent = new Intent(this, SingleTaskActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

This seems counter-intuitive, but the reason is because both X and Y have the same taskAffinity. And taskAffinity trumps launchMode when Android needs to decide how to launch an Activity.

taskAffinity, if not specifically set, defaults to the package name of the application. All activities with the same taskAffinity will be launched into the same task.

This confuses most developers, because the documentation doesn't mention taskAffinity very often.

If you really want to be sure that an Activity will always be the root of its task, no matter how it is launched, you need to use either launchMode="singleTask" or launchMode="singleInstance" and specify taskAffinity="" to indicate that the Activity has no task affinity (ie: it doesn't belong with any other activities).

David Wasser
  • 93,459
  • 16
  • 209
  • 274