New Intent() starts new instance with Android: launchMode="singleTop"
Asked Answered
P

6

61

I have Activity A with android:launchMode="singleTop" in the manifest.

If I go to Activity B, C, and D there I have menu shortcuts to return to my applications root activity (A).

The code looks like this:

Intent myIntent = new Intent(getBaseContext(), MainActivity.class);
startActivity(myIntent);

However, instead of returning to the already existing instance A of my MainActivity.class it creates a new instance -> it goes to onCreate() instead of onNewIntent().

This is not the expected behavior, right?

Pentecostal answered 11/3, 2010 at 11:28 Comment(0)
A
72

This should do the trick.

<activity ... android:launchMode="singleTop" />

When you create an intent to start the app use:

Intent intent= new Intent(context, YourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);

This is that should be needed.

Aarhus answered 11/3, 2010 at 17:55 Comment(1)
This does not work for me.:( below lines of code works fine. <activity ... android:launchMode="singleTop" /> Intent myIntent = new Intent(getBaseContext(), MainActivity.class); myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(myIntent);Airflow
P
28

What actually worked for me in the end was this:

Intent myIntent = new Intent(getBaseContext(), MainActivity.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(myIntent);
Pentecostal answered 11/3, 2010 at 18:51 Comment(1)
You may encounter some unexpected behavior with singleTop activity. A possible solutionYonina
A
14

Quote from the documentation:

The "standard" and "singleTop" modes differ from each other in just one respect: Every time there's new intent for a "standard" activity, a new instance of the class is created to respond to that intent. Each instance handles a single intent. Similarly, a new instance of a "singleTop" activity may also be created to handle a new intent. However, if the target task already has an existing instance of the activity at the top of its stack, that instance will receive the new intent (in an onNewIntent() call); a new instance is not created.

I'm not 100% sure what "already has an existing instance of the activity at the top of its stack" means, but perhaps your activity isn't meeting this condition.

Would singleTask or singleInstance work for you? Or perhaps you could try setting FLAG_ACTIVITY_SINGLE_TOP on the intent you are creating to see if that makes a difference, although I don't think it will.

Alexiaalexin answered 11/3, 2010 at 14:27 Comment(3)
It means that the task stack (application stack) that is currently active has an instance of that activity on top (e.g. an activity is starting another copy of the same activity when it has focus). Other instances of the same activity may exist on other tasks (applications).Kenzie
So if my will is to launch a new instance of activity in the same proccess, but i already FOCUSED on a previouse instance of that activity, how would i do that?Birthday
@Birthday use standard mode I suppose? it says in the doc "Every time there's new intent for a "standard" activity, a new instance of the class is created to respond to that intent."Signesignet
S
7

You can return to the same existing instance of Activity with android:launchMode="singleInstance"

in the manifest. When you return to A from B, may be needed finish() to destroy B.

Supertonic answered 30/5, 2012 at 22:45 Comment(0)
C
2

Firstly, Stack structure can be examined. For the launch mode:singleTop
If an instance of the same activity is already on top of the task stack, then this instance will be reused to respond to the intent.

All activities are hold in the stack("first in last out") so if your current activity is at the top of stack and if you define it in the manifest.file as singleTop

android:name=".ActivityA"
android:launchMode="singleTop"

if you are in the ActivityA recreate the activity it will not enter onCreate will resume onNewIntent() and you can see by creating a notification Not:İf you do not implement onNewIntent(Intent) you will not get new intent.

Intent activityMain = new Intent(ActivityA.this,
                        ActivityA.class);

                activityMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                startActivity(activityMain);




    @Override
        protected void onNewIntent(Intent intent) {

            super.onNewIntent(intent);

            notify("onNewIntent");
        }

        private void notify(String methodName) {

            String name = this.getClass().getName();
            String[] strings = name.split("\\.");

            Notification noti = new Notification.Builder(this)
                    .setContentTitle(methodName + "" + strings[strings.length - 1])
                    .setAutoCancel(true).setSmallIcon(R.drawable.ic_launcher)
                    .setContentText(name).build();
            NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            notificationManager.notify((int) System.currentTimeMillis(), noti);

        }
Catamount answered 1/12, 2014 at 17:0 Comment(0)
O
0

This is because the original A activity is already being destroyed by the time you start it from B, C or D. Therefore, onCreate will be called in stead of onNewIntent(). One way of solving this is to always destroy the existing A(using FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK conjunction when startActivity) before starting a new A, so onCreate will always be called, and you put the code of onNewIntent() into onCreate by checking if getIntent() is the intent you started with.

Olin answered 20/7, 2015 at 21:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.