preface

Recently, I was in charge of part of the upgrade adaptation work in the upgrade of TargetsdkVersion. Later, I will find time to make an in-depth summary of the relevant work in the Android upgrade of TargetsdkVersion. But today I want to address one issue in isolation. Android8.0 “Only fullscreen opaque activities can request orientation” This problem has been found by everyone for nearly a year and a half, and the solution is very complete. The reason why it is called in the analysis is that there are still some problems that have not been explained clearly, and there are some troubles when doing this adaptation yesterday, so here is a brief and comprehensive analysis.

The problem was originally

If the developer sets targetsDkVersion to 27 or above, and the Activity theme in the project is set to transparent, and the orientation of the Activity screen is specified, On Android8.0, a RunRuntimeException will be thrown and the error message will be “Only fullscreen opaque activities can request orientation “.

Then it was pointed out that the problem was caused by a code submission by the Android developers during the development of Android8.0. Click on the portal

From the above submission, we can see that the developers intended to prevent non-full-screen activities from influencing the orientation of the screen. The code snippet traced from the code looks something like this:


if(ActivityInfo isFixedOrientation (requestedOrientation) / / whether to lock the screen direction &&! Fullscreen // not fullscreen &&appinfo.targetsdkversion >= O) {// targetSdkVersion is thrown new for Android8 and above IllegalStateException("Only fullscreen activities can request orientation");
}

Copy the code

Whether it is full-screen or not depends on the following theme attributes:


public static boolean isTranslucentOrFloating(TypedArray attributes) { 
    final boolean isTranslucent = attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent, false); final boolean isSwipeToDismiss = ! attributes.hasValue( com.android.internal.R.styleable.Window_windowIsTranslucent) && attributes.getBoolean( com.android.internal.R.styleable.Window_windowSwipeToDismiss,false); 
    final boolean isFloating = attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating, false);  
    return isFloating || isTranslucent || isSwipeToDismiss;    
}

Copy the code

The problem seems clear at this point, if we set the above themes and lock the screen orientation, the system will throw an exception on Android8.0.

The solution

Let’s talk about the solution:

  • Targetsdkversion reduced to 26 and below
  • Do a check on activities in your project to avoid specifying a transparent theme for activities that also specify a direction

Almost all solutions are essentially based on these two ideas. Well, problem solved. This is basically the end of the online discussion of related issues, such as the following articles and discussions:

java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation

Only fullscreen activities can request orientation? A funny pit!

Kaola Mobile Team’s Blog: Detailed guide to Android O Adaptation

Of course, since there is a solution, so the general analysis is understandable up to this point.

Unexplained problems

But when I read the above articles or questions, I still have some other questions unanswered:

  • If targetsdkversion>=26, Android8.0 should have an exception, but in fact, targetsdkversion=26 is OK, only upgrade to 27 or above will crash

  • Has Android8 really solved this problem since?

Regarding the first question, I continued to look at the source code for Android8.0 and its commit history and found that shortly after this commit, the Android developers made a new commit, which was released at SDK 26.

Allow for SDK 26 Activities to specify orientation when not fullscreen

So there is no problem when we set targetsdkVersion <=26. This exception occurs only if it is greater than 26.

Second, the first release of Android8.1.0 did remove the relevant code, which can be seen in the submission record of Android8.1.0 release portal

conclusion

From the point of view of how this problem arose and was solved, it really can be said that the Android system developers “hand error.” But to be honest, IT’s hard for me to imagine such a screw-up, throwing an exception. Don’t they know that many developers specify transparent themes and fixed directions in their activities? Even after submitting this code, it is not mentioned in the Android8.0 update notes. Oh, all right.