4

Background

When putting my application to background (navigating elsewhere on my Android phone), onStop() is called once, just as expected (Activity lifecycle)

Question rationale: the onStop() contains code which developer expects to be run once.

Question

Why, in case I am locking my phone (single power button press) while in my application's activity - onStop() gets called 3 times?

Update

CASE #1

05-28 14:06:29.322 24347-24347/com... D/DEBUG: onCreate
05-28 14:06:29.380 24347-24347/com... D/DEBUG: onStart
05-28 14:06:29.380 24347-24347/com... D/DEBUG: onResume  

While activity is running, I navigate elsewhere off the app:

05-28 14:06:31.954 24347-24347/com... D/DEBUG: onStop  

At this point I navigate back to the app and open it:

05-28 14:06:34.314 24347-24347/com... D/DEBUG: onStart
05-28 14:06:34.314 24347-24347/com... D/DEBUG: onResume  

CASE #2

05-28 14:09:01.411 24347-24347/com... D/DEBUG: onCreate
05-28 14:09:01.453 24347-24347/com... D/DEBUG: onStart
05-28 14:09:01.453 24347-24347/com... D/DEBUG: onResume  

At this point I lock my device:

05-28 14:35:55.017 30961-30961/com... D/DEBUG: onStop
05-28 14:35:55.278 30961-30961/com... D/DEBUG: onDestroy
05-28 14:35:55.367 30961-30961/com... D/DEBUG: onCreate
05-28 14:35:55.411 30961-30961/com... D/DEBUG: onStart
05-28 14:35:55.419 30961-30961/com... D/DEBUG: onResume
05-28 14:35:55.440 30961-30961/com... D/DEBUG: onStop
05-28 14:35:55.441 30961-30961/com... D/DEBUG: onDestroy
05-28 14:35:55.451 30961-30961/com... D/DEBUG: onCreate
05-28 14:35:55.493 30961-30961/com... D/DEBUG: onStart
05-28 14:35:55.502 30961-30961/com... D/DEBUG: onResume
05-28 14:35:55.830 30961-30961/com... D/DEBUG: onStop
05-28 14:35:55.969 30961-30961/com... D/DEBUG: onDestroy
05-28 14:35:56.004 30961-30961/com... D/DEBUG: onCreate
05-28 14:35:56.044 30961-30961/com... D/DEBUG: onStart
05-28 14:35:56.052 30961-30961/com... D/DEBUG: onResume

I unlock it to see the activity which is still present:

05-28 14:39:38.225 30961-30961/com... D/DEBUG: onResume
05-28 14:39:38.415 30961-30961/com... D/DEBUG: onStop
05-28 14:39:38.416 30961-30961/com... D/DEBUG: onDestroy
05-28 14:39:38.465 30961-30961/com... D/DEBUG: onCreate
05-28 14:39:38.610 30961-30961/com... D/DEBUG: onStart
05-28 14:39:38.624 30961-30961/com... D/DEBUG: onResume

Not sure if it is relevant, but the activity makes use of VLC library to play video. Same result is reached whether the video is currently on playback or not.

Update

My activity, in AndroidManifest.xml is defined with android:screenOrientation="sensorLandscape". The problem disappears once the property is removed (android:screenOrientation="unspecified").

Morphing Coffee
  • 815
  • 1
  • 10
  • 20
  • You may find [this lifecycle chart more explaining](https://www.javatpoint.com/images/androidimages/Android-Activity-Lifecycle.png) -> If oyu want to ensure the code is only executed once, use onDestroy – Zoe May 27 '17 at 20:14
  • can u share ur code ? – akshay_shahane May 27 '17 at 20:46
  • Is `onStart()` also being called 3 times? – David Wasser May 28 '17 at 06:25
  • @akshay_shahane I prefer not to share whole code, but I can point out specific (relevant) requested details about it. – Morphing Coffee May 28 '17 at 13:01
  • @DavidWasser it is. I have updated the question with Logcat for you. – Morphing Coffee May 28 '17 at 13:23
  • @LunarWatcher I am afraid onDestroy might not always be the solution also: [onDestroy called multiple times](https://stackoverflow.com/questions/20398240/ondestroy-called-multiple-times) – Morphing Coffee May 28 '17 at 13:28
  • 1
    You need to figure out why your `Activity` is getting destroyed and recreated. It looks to me like Android is going through a configuration change. You can try to do this yourself and look at the logs. Instead of locking your phone, just change the orientation from portrait to landscape and then back again. I have a feeling this might be what you are seeing. Try that and let me know what you find. – David Wasser May 28 '17 at 18:18
  • 1
    The question you linked regarding `onDestroy()` being called multiple times has only wrong answers. The question is about `Fragment.onDestroy()` and both answers are about `Activity.onDestroy()` and the "correct" answer is wrong :-( Sigh... – David Wasser May 28 '17 at 18:27
  • 1
    @DavidWasser you were right about the change in orientation I believe. It has at least something to do with it (I updated the question details). Although I did not work out how exactly that mechanism works, without trying to prevent multiple calls I solved it keeping the state of what has been called in my answer below. Thanks! – Morphing Coffee Jun 06 '17 at 17:49

1 Answers1

2

Correct issue was pointed out by David Wasser

The cause of activity being destroyed and re-created is similar to change of orientation.
My activity is using android:screenOrientation="sensorLandscape", and I had no clue the "orientation" might change when destroying the activity.

My application depends both on onStop() and onResume() calls, so I will implement onResume() as they are similar.

Solution based on Saving the Instance State

private boolean onResumeCalledAlready;
private String ON_RESUME_CALLED_PREFERENCE_KEY = "onResumeCalled";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Record onResume not called yet
    if (savedInstanceState != null) {
        // Restore value of members from saved state
        onResumeCalledAlready = savedInstanceState.getBoolean(ON_RESUME_CALLED_PREFERENCE_KEY);
    } else {
        onResumeCalledAlready = false;
    }
}

@Override
protected void onResume() {
    super.onResume();
    if (!onResumeCalledAlready) {
        onResumeCalledAlready = true;
        // Do once
        callMeOnlyOnce();
    }
    // Everything else might be called multiple times
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    // Save current onResumeCalledAlready state
    outState.putBoolean(ON_RESUME_CALLED_PREFERENCE_KEY, onResumeCalledAlready);
    super.onSaveInstanceState(outState);
}
Morphing Coffee
  • 815
  • 1
  • 10
  • 20