Intent is not restored correctly after activity is killed if transparent top and single top flags are set

My application has activity starting with FLAG_ACTIVITY_SINGLE_TOP and FLAG_ACTIVITY_CLEAR_TOP because I want to make sure that only one instance of this action is on the top of the stack and all actions on top of the old instance are closed. So far so good.

Next, I wanted to check whether the action is restored correctly after creation more than once and is subsequently destroyed. I try to manually set the intent using Activity.setIntent() when Activity.onNewIntent() is called so that the last intention is returned by Activity.getIntent() . To verify that I activated the "Do not keep actions" option in the developer’s settings, but the intention returned by Activity.getIntent() when the activity is recreated is the very first intention that created it, not the last.

This happens on JB and ICS, I have not tested it in older versions. Am I doing something wrong or misunderstood something in the documents?

+8
android android-intent
source share
2 answers

If you kill your application when it is in the foreground, this is not the same as when Android kills your application (which will only do when your application is in the background). If you kill and then restart the application, it’s the same as starting over from scratch. There is no “recovery." If you add logging to onCreate() , you will see that after you kill and restart the application, the Bundle that is passed to onCreate() is null.

Unfortunately, it’s rather difficult to simulate what happens when Android kills your application.

EDIT: added more stuff after OP comment

Here is a concrete example for discussion. The first without the developer option is "Do not perform actions":

  • ActivityA is the root activity.
  • Let's start ActivityA
  • ActivityA.onCreate() is called
  • ActivityA Now Starts ActivityB Called
  • ActivityB.onCreate() (the activity stack now contains ActivityA ActivityB )
  • ActivityB launches ActivityA using FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP and optional "foo"
  • ActivityA.onNewIntent() is called with an Intent containing FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP and optional "foo"
  • ActivityB.onDestroy() is called because the action stack has been deleted before ActivityA

Now we’ll do the same, but turn on the developer’s option “Do not continue actions” (I highlighted in bold material different from the previous one):

  • ActivityA is the root activity.
  • Let's start ActivityA
  • ActivityA.onCreate() is called
  • ActivityA Now Starts ActivityB Called
  • ActivityB.onCreate() (the activity stack now contains ActivityA ActivityB )
  • Since ActivityA stopped, Android destroys it and calls ActivityA.onDestroy()
  • Note. There is still ActivityAActivityB in the operation stack, although there is currently no instance of ActivityA . Android remembers all state
  • ActivityB launches ActivityA using FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP and optional "foo"
  • Since Android does not have an ActivityA instance to re-enable, it needs to create it, so it does, and then ...
  • ActivityA.onCreate() is called with the same Intent with which it was called when the original instance of ActivityA was created (i.e.: LAUNCH intent without flags and no additional functions)
  • ActivityA.onNewIntent() is called with an Intent containing FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP and optional "foo"
  • ActivityB.onDestroy() is called because the action stack has been deleted before ActivityA

It is important to note that Android always calls onCreate() whenever it creates an instance of activity. Think of it as a constructor Activity If Android needs to recreate an Activity instance because the process was killed or the action was destroyed, it will create a new object, then call onCreate() , and then (if necessary) will call onNewIntent() .

When you call setIntent() , it does not actually change the Intent , which Android saves and restores. This only changes the built-in Intent memory that will be returned from the getIntent() call.

I hope this is clearer now. If not, let me know.

+16
source share

Not sure if you found a solution to this or not, but overriding the onNewIntent (Intent theNewIntent) method for the target activity and calling setIntent (theNewIntent) resolved this for me.

 @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); /* * This overrides the original intent. */ setIntent(intent); } 
+3
source share

All Articles