Android: Behaviour of launchMode="singleTask" not as described?
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开发者_StackOverflow 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. . .
EDIT:
An example demonstrating this behaviour can be found here: http://groups.google.co.uk/group/android-developers/browse_thread/thread/fd8f249803b4688a# 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="singleInstance"
or 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 launchMode
.
If you really want a singleTask
or 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 singleInstance
or singleTask
activity has the following in the manifest in its <activity>
definition:
android:taskAffinity=""
Documentation says:
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 new task.
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...
精彩评论