I’ve been learning Android and have come across an issue with launchMode=”singleTask”. The documentation states that when this attribute is used, the Activity is always launched into a new task as the root Activity. Secondly, the documentation states that if an Intent is targeted at such an Activity when there are Activities sitting above it in its task stack, such Intents are discarded (although the task is still brought to the foreground).
I’ve been playing around with this, and the behaviour I observe is completely different. In particular:
– Activities with launchMode=”singleTask” are not always the root Activity in a task stack. They are just plonked ontop of the existing stack with the same affinity.
– When an Intent is targeted at such an Activity and there are other Activities above it in the stack, the Intent is not discarded. Instead the Activities above it in the stack are discarded. The Intent is then delivered via onNewIntent to the Activity as normal.
Can someone confirm that this is the actual behaviour? If so, why are the documents incorrect? If not what have I done wrong. . .
An example demonstrating this behaviour can be found here:
Sorry for the cross-post, however I was unable to get the example in a decent format to post here…
This is a problem of
taskAffinity. When you start an activity, Android checks the
taskAffinity of the activity that you want to start. If it is the same as the
taskAffinity of the root activity in your task, then it will ignore
launchMode="singleTask" (because those launch modes would require Android to create a new task to launch the activity in) and start the activity in the current task.
Unfortunately, this isn’t well documented, but
taskAffinity takes precedence over
If you really want a
singleInstance activity (which is usually not the right thing to do because it brings with it a whole mess of other nasty things that you are likely to get wrong), then you need to make sure that your
singleTask activity has the following in the manifest in its
FLAG_ACTIVITY_NEW_TASK … produces the same behavior as the
“singleTask” launchMode …
How the activity is started with Intent(FLAG_ACTIVITY_NEW_TASK) depends on activity affinity
If there’s already an existing task with the same affinity as the new
activity, the activity is launched into that task. If not, it begins a
So, there must be equal affinity check for singleTask launchMode.
I can add some experience of odd behaviour to this mode. Maybe the answer of this question helps me too.
I wanted to give my first screen a location-selection search. I wanted to pass the query back to my first Activity. That Activity was search invoking and query receiving. However, “singleTask” destroyed my plans ;(
The Search-intent with the query never reached my first activty. Instead “android.intent.action.MAIN” reached my first activity. When removing “singleTask” the Search-Intent gets through. But then I create several instances of my homescreen.
<activity android:label="@string/app_name" android:name="ActivityStart" android:screenOrientation="portrait" android:launchMode="singleTask"> <intent-filter> <action android:name="android.intent.action.SEARCH" /> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity>
Now I use a TextView instead…