android singleinstance activity not single if back button pressed

Ákos Maróy picture Ákos Maróy · Feb 20, 2013 · Viewed 7.4k times · Source

I encountered an interesting issue, where an Activity is created multiple times, even it is defined as a singleTask or a singelInstance Activity in the manifest. Here is how this can be reproduced. Say, in the main activity:

@Override
protected void onResume() {
    Intent i = new Intent(MainActivity.class, SingleActivity.class);
    startActivity(i);
}

in my SingleActivity, I have:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    Log.i("SingleActivity", "onCreate " + System.identityHashCode(this));
    ...
}

and in the manifest, I have:

    <activity android:name=".SingleActivity"
              android:launchMode="singleInstance"
    />

now, if I start the application, things seem OK, expect in one case: if I press the 'back' button while SingleActivity is in front, it navigates back to MainActivity, where MainActivity.onResume() will create another SingleActivity instance, instead of bringing forward the one that already exists. this is something I know because on the log, a different identity hash code is displayed.

the same seems to be true if the launch mode is singleTask.

the only workaround seems to be to override onBackPressed(), but that seems like an ugly solution.

I wonder what I'm doing wrong

Answer

David Wasser picture David Wasser · Feb 20, 2013

This is a problem of taskAffinity. Because you haven't specified taskAffinity in the manifest on either your MainActivity or your SingleActivity, these 2 activities have the same (default) 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=""

If you need more information, search StackOverflow or Google for "launchmode taskaffinity"