该问题为 Android 8.0 系统 bug。在 8.0 手机上,当应用 targetSdkVersion > 26 时,透明背景的 Activity 如果锁定了屏幕方向,打开该 Activity 就会触发必现的崩溃。触发具体条件为:
①App的targetSdkVersion > 26。
②Activity使用了透明属性的主题:Activity使用的 theme 中 windowIsTranslucent属性为true 或 windowIsFloating属性为true或未配置windowIsTranslucent属性但是windowSwipeToDismiss属性为true。请注意部分常用的系统 theme 也满足条件,例如:@android:style/Theme.Translucent.NoTitleBar、@android:style/Theme.Dialog,以及继承这两个主题的theme。
③Activity强制指定了屏幕方向:
情况1:在 AndroidManifest.xml 中设置了 screenOrientation 属性,并且值为下述的任何一个:landscape、portrait、sensorLandscape、sensorPortrait、reverseLandscape、reversePortrait、userLandscape、userPortrait、locked。
情况2:在Activity的onCreate()中调用了 setRequestedOrientation(int requestedOrientation) 方法,同时requestedOrientation参数为下述的任何一个:ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE、ActivityInfo.SCREEN_ORIENTATION_PORTRAIT、ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE、ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT、ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE、ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT、ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE、ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT、ActivityInfo.SCREEN_ORIENTATION_LOCKED。(或数字形式:0、1、6、7、8、9、11、12、14)
补充说明:关于 setRequestedOrientation(int requestedOrientation) 方法调用,除了上述提到的位置会出现崩溃外,在其他位置调用此接口将不起作用,即不会进行横竖屏切换。这将影响App功能,也是需要适配的。
Android 8.0 系统Activity.java中的相关源码:
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
if (getApplicationInfo().targetSdkVersion > O && 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");
}
}
//其他逻辑略
}
解决方案:
1. 对于 theme 满足条件的 Activity,如果此Activity只需要锁定竖屏,没有横竖屏切换的需求,可以将AndroidManifest.xml中screenOrientation属性值改为:behind。
2. 对于 theme 满足条件的 Activity,如果此Activity有横竖屏切换的需求,需要删除AndroidManifest.xml中screenOrientation属性定义,并且删除代码中调用的setRequestedOrientation接口。同时Activity需要能正常处理横竖屏自动切换的情况。(即:点击按钮切换横竖屏功能将失效)