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.