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).