Android singleTask LaunchMode

I’m finally going to inaugurate the Code category of my blog. I added the category long ago not sure I was ever going to post to it because that sounded suspiciously like work. But this post is so worthwhile, it has to be shared. It’s probably the most helpful post I’ll ever write. After reading it you will gladly send me a portion of the millions and millions of dollars saved in development time tracking down stupid task and back-stack issues. That’ll be thanks enough, I think, and might persuade me to write more Code posts in the future. So let’s get to it.

Imagine you’re an Android developer, cruising along a project, minding your own business. You google stuff all the time and peruse lots of StackOverflow and API docs. Life is swell, minus the occasional “you’re doing it wrong” responses from the Android architects. Whatever, what do they know anyhow? You’ve read the <activity> element docs and about the launchModes and think you understand tasks and the activity stacks too. You might have even used the Intent.FLAG_ACTIVITY flags successfully once or twice. taskAffinity? I’mma just leave that alone unless I need it. But nearly every time you venture beyond launchMode=”standard” things get hairy. Dingleberries, I say!

Have you ever had multiple instances of activities stacking up, so when you are navigating with the back button you see unexpected or old screens? Something is wrong with your task stack–you aren’t using enough tasks, or you tried to use the singleTask launchMode and it doesn’t seem to behave like the documentation says.

Of course, you remember how you put the MAIN action and LAUNCHER category in your intent-filter for your starting activity. You’ve gotta launch the app somehow. Well if you ever try to then make that activity the root of a single task (as you might expect for a starting screen), you will fail miserably. SINGLETASK ACTIVITIES CANNOT HAVE INTENT-FILTERS! It doesn’t matter whether you try starting the activity with implicit intents or not. The existence of the filter breaks it in the most frustrating of ways. Whose bright idea was this? I wasted too many hours of my life googling task affinity and all of the intent flags only to find this is a bug (or documentation lapse) on android’s part.

Thankfully I realized there is an easy workaround once I stopped crying. Use an invisible history-less activity for your launcher to start your actual first activity.

public class LaunchActivity extends FragmentActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // This activity exists only to prevent the SplashActivity from having
    // intent-filters for the MAIN LAUNCHER, which is bugged on
    // launchMode="singleTask"
    Intent splash = new Intent(this, SplashActivity.class);
    startActivity(splash);
    finish();
  }
}

And in your manifest.xml

<activity
  android:name="com.example.LaunchActivity"
  android:label="@string/app_title"
  android:noHistory="true" >
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>
<activity
  android:name="com.example.SplashActivity"
  android:alwaysRetainTaskState="true"
  android:label="@string/app_title"
  android:launchMode="singleTask" >
</activity>

So there are your two activities: a noHistory LaunchActivity, and the first visible singleTask SplashActivity that is started in the onCreate of the LaunchActivity. It’s a pretty simple workaround for a bug that is so poorly documented. And who knows if it is ever going to be fixed, since the Android team thinks you should rarely use anything besides the “standard” launchMode. Typical.

Here are the links you may find helpful

https://groups.google.com/forum/?fromgroups=#!topic/android-developers/d67fbH2uoq4

https://groups.google.com/forum/?fromgroups=#!msg/android-developers/mvkWWuZ50zc/ZWxfI57vG0cJ

About these ads

One thought on “Android singleTask LaunchMode

  1. [...] In fairness, I did write some… I just didn’t publish. Too personal. I got that Code post about the Android singleTask bug done finally, about 4 months after I started it. I’m [...]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s