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

相关推荐
众拾达人1 小时前
Android自动化测试实战 Java篇 主流工具 框架 脚本
android·java·开发语言
吃着火锅x唱着歌2 小时前
PHP7内核剖析 学习笔记 第四章 内存管理(1)
android·笔记·学习
_Shirley3 小时前
鸿蒙设置app更新跳转华为市场
android·华为·kotlin·harmonyos·鸿蒙
hedalei5 小时前
RK3576 Android14编译OTA包提示java.lang.UnsupportedClassVersionError问题
android·android14·rk3576
锋风Fengfeng5 小时前
安卓多渠道apk配置不同签名
android
枫_feng6 小时前
AOSP开发环境配置
android·安卓
叶羽西6 小时前
Android Studio打开一个外部的Android app程序
android·ide·android studio
qq_171538857 小时前
利用Spring Cloud Gateway Predicate优化微服务路由策略
android·javascript·微服务
Vincent(朱志强)9 小时前
设计模式详解(十二):单例模式——Singleton
android·单例模式·设计模式
mmsx9 小时前
android 登录界面编写
android·登录界面