In Split-Screen, Not All HOMEs Are Created Equal

Multi-window modes, such as split-screen on mobile devices, are shaping up to be a never-ending source of unfortunate behavior in edge cases.

This Stack Overflow question is yet another edge case, where your activity’s behavior when the user presses HOME differs, depending on whether the device is in normal mode, in split-screen mode with your activity in the left/top pane, or in split-screen mode with your activity in the right/bottom pane.

We are used to the notion that when the user presses HOME, we are called with onStop(). In fact, onStop() is even more important than before with Android 7.0, as our activities will be paused (but not stopped) a lot more with multi-window. So, whereas we might have used onResume() and onPause() for setting up and tearing down foreground work, we might now switch to onStart() and onStop().

However, onStop() is not always called when the user presses HOME.

If the device is in normal, non-split-screen mode, and the user presses HOME, your foreground activity moves to the background, and onStop() is called.

If the device is in split-screen mode, and your activity is in the bottom or right pane (depending on device orientation), and the user presses HOME, your activity is stopped, so you get an onStop() call. Visually, the activity animates off-screen fully, and if the user presses the RECENTS button, the pane you had been occupying is replaced with the recent-tasks list.

So far, so good.

But what the Stack Overflow question – and July’s bug report – point out is that if your activity is in the top or left pane of split-screen, and the user presses HOME, your activity is not stopped. Arguably, this is because a thin slice of the activity is still visible along that edge, as a hint to the user that they are not really at their home screen. Instead, they are in a state that I will call the “transient home” state.

Since your activity is not called with onStop(), your code keeps chugging along. The quintessential example, cited in the Stack Overflow question, is the video player: the video player keeps playing.

Google’s assertion is that this “transient home” state should indeed be transient:

we see the transition to the home screen as a very quick action is being performed to launch another app and the device will only be in that state for a very short amount of time

(from this issue comment)

I know, it feels weird, but it is supposed to be a mode that users are in only briefly

(from Ian Lake’s comment on his own answer to the Stack Overflow question)

The problem with this theory is that users are not automatons. They will do whatever they like. Some percentage of users will be oblivious to the differences between HOME-in-split-screen and HOME-otherwise. In particular, they will press HOME, and then not continue on to run some other app, but instead just leave their device.

For the video players, games, and other apps that use android:keepScreenOn or setKeepScreenOn() to hold a full wakelock while they are visible… well, that wakelock stays in force, and the device continues draining the battery.

This is bad.

For interactive activities that use full wakelocks, like games, you can kinda work around this. Rather than rely upon onStop() exclusively, also “stop” the activity if the user has not tapped the screen after some number of minutes.

However, this approach does not work for a video player or other activities that are not interactive. You will probably need to release the wakelock in onPause(), and then hope the device screen turns off of its own accord, triggering more lifecycle methods in your activity.

I filed a feature request to get notified either about entering/leaving this “transient home” state or to be notified that the user seems to have abandoned their device in that state, so we can take appropriate steps in our activity.

Find out about new posts on the CommonsBlog via the Atom feed, or follow @CommonsWare on Twitter!