Defect in Android api 24+ split screen and how to work around the bug
What is it?
The defect happens when (the condition might not be exact, since I did not check the source codes)
- There are three activities in a task,
- The top activity calls
finish()
on itself, followed by the second activity callingfinish()
on itself - While the app is in split screen mode
- And the app is not having focus during the above process happens.
What is expected then is that the only remaining activity calls any of onResume
or onStart
or even onCreate
to draw view of the running application. However, what really happens is that the only remaining activity does not call any of the three, resulting in app looking like crashed.
The sample code used in above video is available at this repository.
The defact was reported at Jan 2th 2016, and Google said below on Jan 3th. link
Hi, We have passed this defect on to the development team and will update this issue with more information as it becomes available. Thanks
The work around
In words
Since I cannot just sit and wait until the bug fixes or official guidance is provided, I made a simple work around. It is not perfect because it changes user story and affects user experience, however I thought work around was better than nothing.
- Since the bug happens under special condition - where the activity is destroyed without user action, it is normal to (and we should) notify the user. In my case, we notified user with a toast like “The server closed connection”.
- Since the bug happens only when the problematic app is not activated, or focused, the answer is simple. We need to activate the app before the bug happens. A simple touch will do.
- So, combining 1 and 2, I changed the toast (which disapperas without user action) to a dialog (which needs user click to disappear). And changed the code a little so that the activity distroies itself only after user clicks the dialog.
This way, we can avoid troublesome case without changing lots of codes.
In code
Before
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
private void callFinish() {
finish();
}
After
(*below is pseudo-code)
private boolean paused = false;
@Override
public void onResume() {
super.onResume();
paused = false;
}
@Override
public void onPause() {
super.onPause();
paused = true;
}
private void callFinish() {
// work-around for split screen bug
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && getActivity().isInMultiWindowMode() && paused) {
Dialog dialog = new MyDialog(
"Server closed connection",
"OK",
()-> finish()
);
dialog.show();
} else {
finish();
}
}
Notes:
MyDialog
is not an actual class. I used my dialog class in my code.- Checking
paused()
state is not necessary. However, I did so to minimize impact of the work-around code. The bug does not happen when the activity has the focus, so.
Thank you for reading and hope this can save you some time.