android singleinstance activity not single if back button pressed
Asked Answered
B

2

8

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

Bozuwa answered 20/2, 2013 at 18:19 Comment(2)
Then you should vote for the answer that solved your problem, that's how Stackoverflow works!Fantom
oh, I see you're hunting karma points :) there you go...Antoneantonella
F
5

By default, pressing the BACK key finishes (destroys) the current activity and displays the previous activity to the user.

So, this is impossible to

instead of bringing forward the one that already exists

because no activity exists.

Fantom answered 20/2, 2013 at 18:23 Comment(2)
Are you sure the activity gets destroyed? I haven't looked at the code, but everytime I press back on my phone I can later resume the activity (it never gets destroyed).Beanstalk
this is happening to meZindman
P
14

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"

Polyzoan answered 20/2, 2013 at 22:42 Comment(4)
If the all activities have finished, the task'll be destoryed, so when re-start the activity, it'll re-create activity even if the activity has specified the singleInstance flag.Moloch
What do you mean by "it brings with it a whole mess of other nasty things that you are likely to get wrong"? In my case, I am using launchMode="singleInstance" and android:taskAffinity="" for my Launcher app and everything is OK.Carpic
@Carpic If you have multiple activities in your app, this gets complicated. Also if your app can be started by another app it gets complicated. In general, using singleTask or singleInstance causes more subtle behaviour problems than it solves. It is rarely necessary to use a special launch mode. Most people try using it to solve a problem that they don't really understand, in my experience.Polyzoan
OK. In my case I just do that in my Launcher and I have no problem with that. ThanksCarpic
F
5

By default, pressing the BACK key finishes (destroys) the current activity and displays the previous activity to the user.

So, this is impossible to

instead of bringing forward the one that already exists

because no activity exists.

Fantom answered 20/2, 2013 at 18:23 Comment(2)
Are you sure the activity gets destroyed? I haven't looked at the code, but everytime I press back on my phone I can later resume the activity (it never gets destroyed).Beanstalk
this is happening to meZindman

© 2022 - 2024 — McMap. All rights reserved.