Behaviour of launchMode=“singleTask” not as described?

150 views
Skip to first unread message

Olly

unread,
Sep 10, 2010, 7:00:47 PM9/10/10
to Android Developers
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. . . Here is a
simple way to observe the behaviour:

1. Create a simple main.xml containing two buttons b1 and b2.
2. Create the following Activity:

public class ActivityA extends Activity {

@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Button lButton = (Button) findViewById(R.id.b1);
lButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent lNextIntent = new Intent(ActivityA.this,ActivityA.class);
startActivity(lNextIntent);
}
});

Button lButton2 = (Button) findViewById(R.id.b2);
lButton2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent lNextIntent = new Intent(ActivityA.this,ActivityB.class);
startActivity(lNextIntent);
}
});
}
}

3. Create the second Activity:

public class ActivityB extends ActivityA {

}

4. The manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ojw28.activitytest"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/
app_name">
<activity android:name="ActivityA"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ActivityB"
android:launchMode="singleTask">
</activity>
</application>
</manifest>

5. Launch the application. Press button b1 a couple of times, see what
happens to the task stack using "adb shell dumpsys activity". Multiple
instances of ActivityA are now in the task stack as expected.

Now press button b2. According to the documentation this should launch
an ActivityB instance is a NEW task, as the root Activity of that
task. Use adb to look at the stack. What actually happens is ActivityB
gets put ontop of the current stack, which isn't the documented
behaviour.

Now press button b1 a couple more times. Then press b2 again. Since
the single instance of ActivityB isn't at the top of the stack, the
documentation states that this intent should be ignored. The observed
behaviour is that all ActivityA instances above the ActivityB instance
are discarded from the stack, after which the intent is delivered to
the instance of ActivityB as normal (via onNewIntent - you can
override this method and add a break point to observe this).

joebowbeer

unread,
Sep 10, 2010, 11:30:11 PM9/10/10
to Android Developers
I agree that the documentation is confusing and possibly wrong.

For the second behavior, that of discarding the intent and bringing
the task with the specified activity to the foreground, you should use
"singleTop" instead (despite what the documentation says).

Olly

unread,
Sep 11, 2010, 2:56:54 AM9/11/10
to Android Developers
singleTop behaves as documented for m (i.e. creating a new Activity at
the top of the stack, or reusing one if there is already an Activity
of that type at the top of the stack). I'm pretty sure singleTask is
documented incorrectly though. I'm just wondering whether I've got it
wrong, since this is completely fundamental (its in the "Android
fundamentals" document, so how has no-one else picked up on it?

Olly

unread,
Sep 11, 2010, 3:31:40 AM9/11/10
to Android Developers
I have submitted a bug report with more information here:

http://code.google.com/p/android/issues/detail?id=11160&sort=-id&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars

I think this is a fairly important issue. There needs to be
clarification as to whether the observed behaviour is correct and it
is a documentation error (that would be my guess), or the other way
around.

niko20

unread,
Sep 11, 2010, 9:30:46 AM9/11/10
to Android Developers
I've never had any problems using singleTask - works as described, but
I may not be using Intents to the extent that you do.

-niko

On Sep 11, 2:31 am, Olly <ollywood...@gmail.com> wrote:
> I have submitted a bug report with more information here:
>
> http://code.google.com/p/android/issues/detail?id=11160&sort=-id&cols...

joebowbeer

unread,
Sep 12, 2010, 2:59:44 PM9/12/10
to Android Developers
singleTask is one of four launch modes, but its appealing name and
description belies the fact that it is not recommended for general
use:

http://developer.android.com/guide/topics/manifest/activity-element.html

I suspect you can achieve your desired result using a general-purpose
launch mode ("standard" or "singleTop"), and, instead, clearing
ActivityB's taskAffinity and/or adding FLAG_ACTIVITY_NEW_TASK to the
intent that launches ActivityB.

On Sep 10, 11:56 pm, Olly <ollywood...@gmail.com> wrote:
> singleTop behaves as documented for me (i.e. creating a new Activity at
Reply all
Reply to author
Forward
0 new messages