In my application there is an activity started using the FLAG_ACTIVITY_SINGLE_TOP and FLAG_ACTIVITY_CLEAR_TOP flags because I want to make sure that only one instance of that activity is at the top of the stack and all activities on top of the old instance are closed. So far so good.
Next I wanted to test if the activity restores correctly after being created more than once and successively destroyed. I take care to manually set the intent using Activity.setIntent()
when Activity.onNewIntent()
is called so that the most recent intent is returned by Activity.getIntent()
. In order to test that I activated the "Don't keep activities" option in the developer options, but the intent returned by Activity.getIntent()
when the activity is re-created is the very first intent that created it and not the most recent one.
This happens on JB and ICS, I haven't tested it on older versions. Am I doing something wrong or did I misunderstand something in the docs?
Not sure if you've found a solution to this or not, but overriding the onNewIntent(Intent theNewIntent) method for the target activity & calling setIntent(theNewIntent) solved it for me.
If you kill your app while it is in the foreground, this is not the same as when Android kills your app (which it will only do when your app is in the background). If you kill and then restart the app, it is like starting it all over again from scratch. There is no "restore" going on here. If you add logging to
onCreate()
you should see that after you kill and restart your app, theBundle
that is passed toonCreate()
is null.Unfortunately it is pretty difficult to simulate what happens when Android kills your app.
EDIT: Added more stuff after OP's comment
Here's a concrete example for discussion purposes. First without the developer option "Don't keep activities":
ActivityA
is the root activityActivityA
ActivityA.onCreate()
is calledActivityA
now startsActivityB
ActivityB.onCreate()
is called (The activity stack now containsActivityA
->ActivityB
)ActivityB
startsActivityA
withFLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP
and an extra "foo"ActivityA.onNewIntent()
gets called with theIntent
containingFLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP
and an extra "foo"ActivityB.onDestroy()
is called since the activity stack was cleared back toActivityA
Now, let's do the exact same thing but enable the developer option "Don't keep activities" (I've highlighted in bold the stuff that is different from the previous scenario):
ActivityA
is the root activityActivityA
ActivityA.onCreate()
is calledActivityA
now startsActivityB
ActivityB.onCreate()
is called (The activity stack now containsActivityA
->ActivityB
)ActivityA
has stopped, Android destroys it and callsActivityA.onDestroy()
ActivityA
->ActivityB
, even though there is no instance ofActivityA
at the moment. Android remembers all the stateActivityB
startsActivityA
withFLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP
and an extra "foo"ActivityA
to reactivate, it needs to create one, so it does and then...ActivityA.onCreate()
is called with the sameIntent
that it was called with when the original instance ofActivityA
was created (ie: LAUNCH intent with no flags and no extras)ActivityA.onNewIntent()
gets called with theIntent
containingFLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP
and an extra "foo"ActivityB.onDestroy()
is called since the activity stack was cleared back toActivityA
The important thing to note here is that Android always calls
onCreate()
whenever it creates an activity instance. Think of it like the constructor of anActivity
. If Android has to recreate an instance of anActivity
because the process was killed or the activity was destroyed, then it will instantiate a new object, then callonCreate()
and then (if necessary) it will callonNewIntent()
.When you call
setIntent()
this doesn't actually change theIntent
that Android saves and restores. That only changes the in-memoryIntent
that will be returned from a call togetIntent()
.I hope this is clearer now. If not, please let me know.