Android "single top" launch mode and onNewIntent method Android "single top" launch mode and onNewIntent method java java

Android "single top" launch mode and onNewIntent method


Did you check if onDestroy() was called as well? That's probably why onCreate() gets invoked every time instead of onNewIntent(), which would only be called if the activity is already existing.

For example if you leave your activity via the BACK-button it gets destroyed by default. But if you go up higher on the activity stack into other activities and from there call your ArtistActivity.class again it will skip onCreate() and go directly to onNewIntent(), because the activity has already been created and since you defined it as singleTop Android won't create a new instance of it, but take the one that is already lying around.

What I do to see what's going on I implement dummy functions for all the different states of each activity so I always now what's going on:

@Overridepublic void onDestroy() {    Log.i(TAG, "onDestroy()");    super.onDestroy();}

Same for onRestart(), onStart(), onResume(), onPause(), onDestroy()

If the above (BACK-button) wasn't your problem, implementing these dummies will at least help you debugging it a bit better.


The accepted answer is not quite correct. If onDestroy() was called previously, then yes, onCreate() would always be called. However, this statement is wrong:"If you go up higher on the activity stack into other activities and from there call your ArtistActivity.class again it will skip onCreate() and go directly to onNewIntent()"

The "singleTop" section of http://developer.android.com/guide/components/tasks-and-back-stack.html explains plainly how it works (attention to bold text below; I've also proven this through my own debugging):

"For example, suppose a task's back stack consists of root activity A with activities B, C, and D on top (the stack is A-B-C-D; D is on top). An intent arrives for an activity of type D. If D has the default "standard"launch mode, a new instance of the class is launched and the stack becomes A-B-C-D-D. However, if D's launch mode is "singleTop", the existing instance of D receives the intent through onNewIntent(), because it's at the top of the stackā€”the stack remains A-B-C-D. However, if an intent arrives for an activity of type B, then a new instance of B is added to the stack, even if its launch mode is "singleTop"."

In other words, starting an activity through SINGLE_TOP will only reuse the existing activity if it is already at the top of the stack. It won't work if another activity in that same task is at the top (for example, the activity that is executing startActivity(SINGLE_TOP)); a new instance will be created instead.

Here are two ways to fix this so that you get the SINGLE_TOP behavior that you want -- the general purpose of which is to reuse an existing activity, instead of creating a new one...

First way (as described in the comment section of the accepted answer): You could add a launchMode of "singleTask" to your Activity. This would force onNewIntent() because singleTask means there can only be ONE instance of a particular activity in a given task. This is a somewhat hacky solution though because if your app needs multiple instances of that activity in a particular situation (like I do for my project), you're screwed.

Second way (better):Instead of FLAG_ACTIVITY_SINGLE_TOP, use FLAG_ACTIVITY_REORDER_TO_FRONT. This will reuse the existing activity instance by moving it to the top of the stack (onNewIntent() will be called as expected).

The main purpose of FLAG_ACTIVITY_SINGLE_TOP is to prevent the creation of multiple instances of an Activity. For instance, when that activity can be launched via an intent that comes from outside of your application's main task. For internal switching between activities in my app, I've found that FLAG_ACTIVITY_REORDER_TO_FRONT is generally what I want instead.


Set this flag to your intent:

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP)