4

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.

David Wasser
  • 93,459
  • 16
  • 209
  • 274
rrbrambley
  • 513
  • 5
  • 15

3 Answers3

2

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`.

David Wasser
  • 93,459
  • 16
  • 209
  • 274
  • if stack stack builder always recreate things. that does not make much sense, during an app usage – Remario Apr 21 '17 at 09:11
  • @Remario But that doesn't change the fact that that is exactly what it does. It builds the task stack completely new! I never use `TaskStackBuilder` and I always suggest that developers not use it unless they understand exactly what it does. – David Wasser Apr 22 '17 at 19:13
  • @Remario You should open a new question, as having this discussion in coments isn't useful for other developers. Please state exactly what you want to know, or what problem you are having. Thanks. – David Wasser Apr 22 '17 at 19:19
0
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

add this flag to the notification intent

Michaël
  • 3,679
  • 7
  • 39
  • 64
  • This does not solve the problem. A new instance of the activity is being created and onCreate() is being called. – rrbrambley Dec 23 '14 at 17:51
0

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

Darpan
  • 5,623
  • 3
  • 48
  • 80
  • This does not solve the problem. A new instance of the activity is being created and onCreate() is being called. – rrbrambley Dec 23 '14 at 17:51