1. 程式人生 > >關於crash " Only fullscreen activities can request orientation "來源及解決方案

關於crash " Only fullscreen activities can request orientation "來源及解決方案

最近遇到一個奇怪的bug。就是:

targetSdk=27 並且android SDK版本是26(Android 8.0.0)或者27(Android 8.1.0)時,此時在應用中,如果把一個Activity的主題設定為透明並且螢幕方向固定時,就會crash,如下:java.lang.IllegalStateException:Only fullscreen activities can request orientation

現已查明,此為Android 8.0.0 Android 8.1.0bug(Android 9.0.0已修改)

具體原始碼如下:

protected void onCreate(@Nullable Bundle savedInstanceState) {
    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);

    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();

        if (isTranslucentOrFloating) {
            throw new IllegalStateException(
                    "Only fullscreen opaque activities can request orientation");
        }
    }

Android 9.0.0已去掉此段程式碼,證明在Android 9.0.0已修復此bug。

如何產生此bug ?舉例如下:

比如對Activity設定了主題:android:theme="@android:style/Theme.Translucent.NoTitleBar" 又設定了固定方向:android:screenOrientation="portrait" 或者在程式碼中設定的固定方向:setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

此時,就會報crash :java.lang.IllegalStateException:Only fullscreen activities can request orientation

解決方案:第一種:讓主題透明Translucent Activity 固定方向不要同時存在。 第二種:保持現狀,把 targetSdk 不要設定為27(設定為別的版本都可以)

如果採用第一種方案修改,程式碼判斷如下:

if (activity.getApplicationInfo().targetSdkVersion == 27 && (Build.VERSION.SDK_INT == 26 ||      Build.VERSION.SDK_INT == 27)) {
    //ToDoSomething
}

此bug 是典型的谷歌程式設計師的bug ,憑什麼不讓開發者設定透明和固定方向同時存在?唉,谷歌大爺犯了這個錯,咱們開發者也沒辦法,只能去適配。