12

I have an activity that needs to turn on the screen when it is started (just in case the screen was off). So in my onCreate, I have:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
            |WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
            |WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
            |WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);

Using this straightforward combination, I am able to cause my activity to display whenever it is started from my background service (yes, this is a legitimate case).

The problem, however, is that there is a very strange lifecycle behavior when I start up my activity in such a case. Using extensive logging, I was able to figure out that the following 7-step process happens immediately after the activity is started:

  1. onCreate
  2. onStart
  3. onResume
  4. onPause
  5. onStop
  6. onStart
  7. onResume

See that? For a simple activity start, onStart is called twice. And more importantly, onStop is mysteriously called, even though the activity was just started - and nothing happened that would cause it to stop.

I have tested this in many different scenarios and it appears that this strange behavior only happens when the screen is off and the activity is launched after it was destroyed. If the screen is on, or if the activity was stopped [but not yet destroyed] the activity launches normally, and onStart is only called once.

Bottom line: it appears that when my activity is launched and the screen is forced on, Android starts the activity, then stops it, and then starts it again for no apparent reason.

So: why is this happening? And is there anything I can do to workaround this (so that onStop isn't called until there is a legitimate cause for it to be)?


Notes:

  • The activity in question is using the singleTask launchmode
  • I have tried disabling the keyguard / lock but it has no effect
  • I am witnessing this behavior on a Samsung Galaxy Tab 10.1 running Android 3.2. I have not tested whether this applies to anything else...
yydl
  • 24,284
  • 16
  • 65
  • 104
  • I'm having a similar behaviour when the activity needs to be rotated. In my case the activity has an unspecified orientation in the AndroidManifest. During onCreate I set the orientation on the basis of my state machine. When the orientation I set is not the current one that means that the activity needs to be rotated, I see the weird life-cycle that you described. Did you find the answer? – kingston Jul 31 '12 at 15:40
  • I have also checked that onPostResume is called before the onPause. – kingston Jul 31 '12 at 15:47
  • 1
    The solution described here worked for me: [OnPause and OnStop() called immediately after starting activity](http://stackoverflow.com/questions/25369909/onpause-and-onstop-called-immediately-after-starting-activity) – cyberhuman Jul 14 '15 at 13:37

3 Answers3

2

I had a similar problem here: Activity Lifecycle X Power Button X Lock Screen

The problem was that as my activity was forced landscape, when I turned on the screen it showed the lock screen in portrait and it was causing a configuration change and hence destroying the current activity.

The solution was to add a android:configChanges="orientation" on the Activity in my AndroidManifest.xml.

Community
  • 1
  • 1
thiagolr
  • 6,909
  • 6
  • 44
  • 64
  • 1
    Good call. But there is one more to add: android:configChanges="keyboardHidden|orientation". With ICS+ you will need android:configChanges="keyboardHidden|orientation|screenSize". – Swifty McSwifterton Sep 14 '12 at 17:26
2

As suggested by @cyberhuman, the answer to this question OnPause and OnStop() called immediately after starting activity pointed me to the right direction.

My issue with the activity completing a full 'dummy' lifecycle before being actually displayed to the user was that my attempt to play the ringtone when the activity became visible was directly muted by the additional, subsequent "onStop()", and using flags to make the activity behave properly when launched when screen is off/when screen is locked/when screen is on/when activity is running in the background was not possible.

I finally solved my issue by overriding the onWindowFocusChanged(boolean hasFocus) method and launching the ringtone from there. Putting it here in case somebody has the same issue.

Community
  • 1
  • 1
Marcino
  • 196
  • 8
-3

You could check for the situation in onStart, set a static or global variable, and then check the variable in onStop to override the standard behavior.

Mundi
  • 79,884
  • 17
  • 117
  • 140
  • 1
    But how would I differentiate between "good" cases and "bad" cases of onStop? – yydl May 31 '12 at 07:18
  • Yes, but as I write, this doesn't always happen -- only where the screen was off. So if the screen is on, your method won't work – yydl May 31 '12 at 07:20
  • It will, because you checked the state in `onStart` and set the variable accordingly. – Mundi May 31 '12 at 07:24
  • There is no difference between being launched from when the screen is off or on. So there's no way to tell and therefore no way to set a variable. – yydl May 31 '12 at 07:26
  • You should be able to get this information with `getWindow().getAttributes()` – Mundi May 31 '12 at 07:29
  • What information should I be able to get, and how would I get it? – yydl May 31 '12 at 07:31
  • Check out [the Android documentation](http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html) for the flags you can check. – Mundi May 31 '12 at 08:21
  • Those flags are set (or not set) regardless of how the activity is launched. – yydl Jun 01 '12 at 01:43