關於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.0的bug(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 ,憑什麼不讓開發者設定透明和固定方向同時存在?唉,谷歌大爺犯了這個錯,咱們開發者也沒辦法,只能去適配。