2

According to http://developer.android.com/training/basics/activity-lifecycle/recreating.html

There are various ways to trigger activity recreation.

  • Screen rotation
  • Low memory condition

I realize screen rotation and low memory condition yield quite different behavior.

One of the obvious observations is that, for restore activity from long pressed home, it will destroy and re-create Application as well.

For screen rotation, it will not yield such behavior.

May I know, how can Activity or Fragment differentiate both cases?

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Check whether we're recreating a previously destroyed instance
    if (savedInstanceState != null) {
        // Is this caused by screen rotation? Or restoration from low memory condition?
        // How can we differentiate among "screen rotation", or "restoration from low memory condition"?

    } else {
    }
    ...
}

p/s To produce low memory condition, here are the steps to be done.

  1. Press home to put the app in back stack.
  2. Launch a memory intensive app.
  3. Press home.
  4. Repeat steps 2-3 for 5 times for other apps.
  5. Launch the 1st app again.
  6. You will realize savedInstanceState is not null. However, at the same time, you will realize that current running Application instance is different than the first time launched's.

Besides static members will become uninitialized when restoring from low memory condition, I also encounter some weird stuffs

  1. Launch an child activity from parent activity via startActivityForResult
  2. Perform the above 6 steps.
  3. Close the child activity.
  4. We can observe parent activity's fragment is having the following life cycle. onCreate -> onActivityResult -> onResume

We are expecting onCreate -> onResume -> onActivityResult

Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875

2 Answers2

3

One of the obvious observations is that, for restore activity from long pressed home, it will destroy and re-create Application as well.

No, it will not.

If your process was terminated, then when a new process is created for you (not matter how you launch the app), a new Application is created as part of that new process. This does not directly have anything to do with "restore activity from long pressed home".

May I know, how can Activity or Fragment differentiate both cases?

Ideally, they don't care. The only reason they would care is if they are dependent upon static data members, which may or may not be initialized, in which case the way that you are using those static data members is problematic.

My previous assertion, that savedInstanceState would be non-null, is incorrect, and for that I apologize. The primary scenario for savedInstanceState is a configuration change. However, I was forgetting that launching from the recent-tasks list ("restore activity from long pressed home") will also pass in the last saved instance state. Launching by other means, such as from the home screen launcher, would pass in null for savedInstanceState.

If you absolutely must distinguish between your-process-was-terminated and other scenarios, check some static data member to see if it is initialized or not.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Believe me. It does and I had tested it many times. One of the key steps to reproduce such case is that, you need to launch several other apps (To encourage OS to "kill" the app which is currently in back stack), before restoring the app from long pressed home. – Cheok Yan Cheng Jul 18 '13 at 18:26
  • @CheokYanCheng: By your own admission, your test proves my point. If "restore activity from long pressed home, it will destroy and re-create Application as well", then it would do that **all of the time**. As you documented, it does not. "launch several apps (Preferably memory intensive app, let's say 5)" may cause Android to terminate your process due to low memory, and terminating your process results in a new `Application`. This does not directly have anything to do with "restore activity from long pressed home". – CommonsWare Jul 18 '13 at 18:31
  • OK. I think I should refined the title "How to differentiate activity recreation is caused by screen rotation, or low memory condition"? Does that makes the thing clearer? – Cheok Yan Cheng Jul 18 '13 at 18:34
  • @CheokYanCheng: It certainly makes it more accurate. And, as my answer notes, if `savedInstanceState` is not `null`, you were recreated due to a configuration change, otherwise you were recreated for other reasons. – CommonsWare Jul 18 '13 at 18:35
  • Does your "configuration change" include low memory condition as well? – Cheok Yan Cheng Jul 18 '13 at 18:43
  • @CheokYanCheng: No. http://developer.android.com/guide/topics/resources/runtime-changes.html – CommonsWare Jul 18 '13 at 18:52
  • Then `savedInstanceState` is not `null`, is not necessary recreated due to configuration change. It can also caused by restoration from low memory condition too. – Cheok Yan Cheng Jul 18 '13 at 19:08
  • @CheokYanCheng: No. **The only condition under which `savedInstanceState` is not `null` is if your activity is being recreated due to a configuration change**. Configuration changes include screen rotations and other events as noted in the linked-to documentation. Process termination is not a configuration change. – CommonsWare Jul 18 '13 at 19:12
  • Did you try out the 6 steps I mention in question? Those steps are not configuration change. But it causes `savedInstanceState` is not `null` – Cheok Yan Cheng Jul 18 '13 at 19:15
  • @CheokYanCheng: My sincere apologies. I was forgetting something. See updated answer. – CommonsWare Jul 18 '13 at 19:24
  • The reason I care for it is that, when such scenario happen, I will encounter some abnormal activity life cycle. I update my question to reflect on this. But checking on static member, is a good way to find out whether such "low memory condition" has happened. – Cheok Yan Cheng Jul 19 '13 at 07:20
0

check this out -https://developer.android.com/reference/android/app/Activity#isChangingConfigurations()

You can simply save value returned by isChangingConfigurations() in bundle and then check it in onCreate

Filipkowicz
  • 639
  • 6
  • 17