闪退日志
php
java.lang.RuntimeException: Unable to start activity ComponentInfo{cn.xxx.xxx/xx.xx.xx.xx.xxxxxActivity}: java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3046)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1688)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6809)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
at android.app.Activity.onCreate(Activity.java:995)
at androidx.core.app.ComponentActivity.onCreate(SourceFile:1)
at androidx.activity.ComponentActivity.onCreate(SourceFile:11)
at androidx.fragment.app.FragmentActivity.onCreate(SourceFile:1)
at cn.eeo.basic.BaseActivity.onCreate(SourceFile:31)
at cn.eeo.lms.base.BaseViewActivity.onCreate(SourceFile:1)
at android.app.Activity.performCreate(Activity.java:6998)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1230)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2899)
... 9 more
java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
at android.app.Activity.onCreate(Activity.java:995)
at androidx.core.app.ComponentActivity.onCreate(SourceFile:1)
at androidx.activity.ComponentActivity.onCreate(SourceFile:11)
at androidx.fragment.app.FragmentActivity.onCreate(SourceFile:1)
at cn.eeo.basic.BaseActivity.onCreate(SourceFile:31)
at cn.eeo.lms.base.BaseViewActivity.onCreate(SourceFile:1)
at android.app.Activity.performCreate(Activity.java:6998)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1230)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2899)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3046)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1688)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6809)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
问题原因
Android8.0系统上要求只有不透明的全屏Activity才可以设置横竖屏,半透明/对话框等不可以设置横竖屏 即android:screenOrientation="portrait"
与主题风格<item name="android:windowIsTranslucent">true</item>
在Android8.0系统会抛异常
源码分析
Android8.0系统源码
java
@MainThread
@CallSuper
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");
}
}
//省略部分源代码....
}
//查看ActivityInfo的isTranlucentOrFloating()方法
/**
* 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;
}
可以看到当activity设置了方向且设置了半透明Window_windowIsTranslucent,就会抛出Only fullscreen opaque activities can request orientation
异常
解决方案
由于是screenOrientation 和 windowIsTranslucent 都设置了导致的问题,我们只需要让一个条件不满足就可以绕过这个限制。首先不考虑去掉screenOrientation,因为会影响业务要求;所以只能从windowIsTranslucent下手。我们只需要在Android8.0的系统上设置windowIsTranslucent=false就可以了
- 创建values-v26资源目录,用于设置Android8.0及以后的系统上的风格配置
xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="ActivityTransparentStyle" parent="@style/Theme.AppCompat.Light.NoActionBar">
<item name="android:windowIsTranslucent">false</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowLightStatusBar">true</item>
<!-- <item name="android:windowFullscreen">true</item>-->
</style>
</resources>
- 需要保证Android8.1以后的版本可以正常使用透明效果,所以需要创建values-v27资源目录,并保持原来的透明设置
xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="ActivityTransparentStyle" parent="@style/Theme.AppCompat.Light.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowLightStatusBar">true</item>
<!-- <item name="android:windowFullscreen">true</item>-->
</style>
</resources>
这样在Android8.0的系统就不会使用半透明效果,其他系统依旧使用半透明效果,解决闪退问题。