singleTop Activity sometimes being created even when on top of stack

1.2k Views Asked by At

I have an Activity whose launchMode is singleTop (in the manifest). My understanding is that if an Activity is singleTop and it is on top of the activity stack, then launching an the Activity with a new Intent will actually result in onNewIntent() being called on the Activity, without a new instance of the activity being created (an thus, onCreate() is not called).

This Activity runs a foreground service that shows an ongoing notification. When selected, this notification simply brings the user back into the Activity that is on top of the stack (there are no activities launched from this singleTop activity). My problem is that when the notification is selected, sometimes a new instance of the Activity is created – even when it is visibly already on top of the stack. This is problematic for my Activity because its behavior is intended to be different for the cases in which it is killed in the background and relaunched (vs. just brought to front with onNewIntent()). The code my service uses to present the notification is as follows:

TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);

Intent notificationIntent = new Intent(this, MyProblematicActivity.class);
notificationIntent.putExtra(EXTRA_MY_DATA, "MyData");
stackBuilder.addNextIntent(notificationIntent);

PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

Notification.Builder notificationBuilder = new Notification.Builder(getApplicationContext()).
        setSmallIcon(smallIconResourceId).
        setContentTitle(contentTitle).
        setContentText(contentText).
        setAutoCancel(false).
        setOngoing(true).
        setContentIntent(pendingIntent);

startForeground(MY_NOTIF_ID, notificationBuilder.build());

I say that this behavior sometimes occurs, and when it does, it will do so repeatedly. For example:

  1. MyProblematicActivity is launched for the first time
  2. Service starts and notification is presented
  3. Notification is selected.
  4. MyProblematicActivity is created again (service is already started, notification already showing).
  5. Repeat 2-4 forevs.

Occasionally, after #3, MyProblematicActivity's onNewIntent() is called without creating a new instance, and things worked as expected.

I don't have any idea why this could be happening. Can the state activity at the root of the task have any affect on how my singleTop activity behaves? FWIW, the Activity that creates MyProblematicActivity is a singleTask Activity.

3

There are 3 best solutions below

1
On

I am answering with same thing what Komal said, but only to explain the reason behind this whole thing,

if you use singleTop, new instance will only not be called if you have your target activity on the top of the stack, if it is not on top then a new intent receives in onNewIntent(); thus new instance is created.

So,

add flag Intent.FLAG_ACTIVITY_CLEAR_TOP

if you navigate up to an activity on the current stack, the behavior is determined by the parent activity's launch mode. If the parent activity has launch mode singleTop (or the up intent contains FLAG_ACTIVITY_CLEAR_TOP), the parent is brought to the top of the stack, and its state is preserved. The navigation intent is received by the parent activity's onNewIntent() method. If the parent activity has launch mode standard (and the up intent does not contain FLAG_ACTIVITY_CLEAR_TOP), the current activity and its parent are both popped off the stack, and a new instance of the parent activity is created to receive the navigation intent.

Documentation

1
On
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

add this flag to the notification intent

3
On

You have this problem because you are using TaskStackBuilder. The behaviour ofTaskStackBuilderis that it always resets the task, which means that theActivitywill be created again. Don't useTaskStackBuilderfor this, just callPendingIntent.getActivity()to get aPendingIntentto add to yourNotification`.