解决Android8.0 Only fullscreen activities can request orientation闪退

闪退日志

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的系统就不会使用半透明效果,其他系统依旧使用半透明效果,解决闪退问题。

相关推荐
张拭心6 分钟前
春节后,有些公司明确要求 AI 经验了
android·前端·人工智能
张拭心16 分钟前
Android 17 来了!新特性介绍与适配建议
android·前端
Kapaseker3 小时前
Compose 进阶—巧用 GraphicsLayer
android·kotlin
黄林晴3 小时前
Android17 为什么重写 MessageQueue
android
阿巴斯甜1 天前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker1 天前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95271 天前
Andorid Google 登录接入文档
android
黄林晴1 天前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab2 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿2 天前
Android MediaPlayer 笔记
android