java.lang.IllegalStateException: Only fullscreen opaque activities

異常產生緣由

exception log

好比:java

Caused by: java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
    at android.app.Activity.onCreate(Activity.java:1081)
    at android.support.v4.app.SupportActivity.onCreate(SupportActivity.java:66)
    at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:297)
    at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:84)
    at com.nut.blehunter.ui.DialogContainerActivity.onCreate(DialogContainerActivity.java:43)
    at android.app.Activity.performCreate(Activity.java:7372)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1218)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3147)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302) 
    at android.app.ActivityThread.-wrap12(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891) 
    at android.os.Handler.dispatchMessage(Handler.java:108) 
    at android.os.Looper.loop(Looper.java:166)
複製代碼

源碼分析

The code that triggered the exception in Activity.javaandroid

//Need to pay attention mActivityInfo.isFixedOrientation() and ActivityInfo.isTranslucentOrFloating(ta)
    if (getApplicationInfo().targetSdkVersion >= O_MR1 && mActivityInfo.isFixedOrientation()) {
        final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window);
        final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta);
        ta.recycle();
        //Exception occurred
        if (isTranslucentOrFloating) {
            throw new IllegalStateException(
                    "Only fullscreen opaque activities can request orientation");
        }
    }
複製代碼

mActivityInfo.isFixedOrientation():bash

/**
        * Returns true if the activity's orientation is fixed. * @hide */ public boolean isFixedOrientation() { return isFixedOrientationLandscape() || isFixedOrientationPortrait() || screenOrientation == SCREEN_ORIENTATION_LOCKED; } /** * Returns true if the activity's orientation is fixed to portrait.
        * @hide
        */
        boolean isFixedOrientationPortrait() {
            return isFixedOrientationPortrait(screenOrientation);
        }
        /**
        * Returns true if the activity's orientation is fixed to portrait. * @hide */ public static boolean isFixedOrientationPortrait(@ScreenOrientation int orientation) { return orientation == SCREEN_ORIENTATION_PORTRAIT || orientation == SCREEN_ORIENTATION_SENSOR_PORTRAIT || orientation == SCREEN_ORIENTATION_REVERSE_PORTRAIT || orientation == SCREEN_ORIENTATION_USER_PORTRAIT; } /** * Determines whether the {@link Activity} is considered translucent or floating. * @hide */ 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; } 複製代碼

當 TargetSdkVersion>=27, 而且使用 SCREEN_ORIENTATION_LANDSCAPE, SCREEN_ORIENTATION_PORTRAIT 和其餘相關的屬性,而且使用 windowIsTranslucent, windowIsFloating, windowSwipeToDismiss 屬性纔會產生;google意識到這個問題,在後面的版本修復了此係統bug。app

異常產生必要條件

一、targetSDKVersin>=27
二、在android8.0.0系統上
三、Activity設置了android:screenOrientation="portrait"而且還設置了主題帶有trueide

好比下面代碼就會產生:oop

<activity
        android:name=".activities.FilterActivity"
        android:theme="@style/TextStyle"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="stateHidden|adjustResize" />
複製代碼
<style name="TextStyle" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowIsTranslucent">true</item>
</style>
複製代碼

修改方案

方案一

一、
a、在AndroidManifest.xml中隊Activity移除android:screenOrientation="portrait"或者設置爲android:screenOrientation="unspecified"源碼分析

b、在Activity的onCreate中設置
  if (Build.VERSION.SDK_INT == 26) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
    } else {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }ui

方案二

二、設置如下屬性爲falsegoogle

<item name="android:windowIsTranslucent">false</item>  
複製代碼
相關文章
相關標籤/搜索