当前位置:   article > 正文

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

java.lang.illegalstateexception: only fullscreen opaque activities can reque

Android O(API26、27)版本有一个bug,在设置方向属性时会crash:

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

出现场景:

1)manifest中
android:screenOrientation="portrait"

2)代码中
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

原因

这个问题貌似已经被广泛的讨论了,最终我们锁定了April 26的一个commit:

Prevent non-fullscreen activities from influencing orientation · aosp-mirror/platform_frameworks_base@3979159

这个改动中抛出异常有关的代码如下:

if (ActivityInfo.isFixedOrientation(requestedOrientation) 
    && !fullscreen
    && appInfo.targetSdkVersion >= O) {
    throw new IllegalStateException("Only fullscreen activities can request orientation");
}
  • 1
  • 2
  • 3
  • 4
  • 5

基本的意思是说,“fullscreen”为否的activity是不能锁定orientation的,否则抛出异常。下面,我们在看一下“fullscreen”如何定义的。

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;    
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

根据上面的定义,如果一个Activity的Style符合下面三个条件之一,认为不是“fullscreen”:

“windowIsTranslucent”为true;
“windowIsTranslucent”为false,但“windowSwipeToDismiss”为true;
“windowIsFloating“为true;

综上可见,这个改动的目的是想阻止非全屏的Activity锁定屏幕旋转,因为当前Activity是透明的,浮动的或可滑动取消的,是否锁屏应该由全屏的Activity决定,而不是并没有全部占据屏幕的Activity决定。
参考:https://zhuanlan.zhihu.com/p/32190223

解决

1)方法一 不固定方向
比如去除 android:screenOrientation="portrait",或者不调用设置方向的代码

2)方法二 固定方向时判断去除Android O
移除manifest文件里的screenOrientation属性,并在Activity的onCreate方法里设置屏幕方向:

//android O fix bug orientation
    if (android.os.Build.VERSION.SDK_INT != Build.VERSION_CODES.O) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }
  • 1
  • 2
  • 3
  • 4

3)方法三 取消Activity主题里的windowIsTranslucent属性或者windowSwipeToDismiss属性或者windowIsFloating属性

a. 在res资源文件夹下新建两个包:values-v26 values-v27
b. 两个包内 style.xml文件中:

<style name="XXX">
        <item name="android:windowIsTranslucent">false</item>
    </style>
  • 1
  • 2
  • 3
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/375909
推荐阅读
相关标签
  

闽ICP备14008679号