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

相关推荐
Mr_sun.35 分钟前
Day09——入退管理-入住-2
android·java·开发语言
ujainu2 小时前
告别杂乱!Flutter + OpenHarmony 鸿蒙记事本的标签与分类管理(三)
android·flutter·openharmony
常利兵2 小时前
Android内存泄漏:成因剖析与高效排查实战指南
android
·云扬·2 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
野生技术架构师2 小时前
SQL语句性能优化分析及解决方案
android·sql·性能优化
doupoa4 小时前
内存指针是什么?为什么指针还要有偏移量?
android·c++
非凡ghost4 小时前
PowerDirector安卓版(威力导演安卓版)
android·windows·学习·软件需求
独行soc5 小时前
2026年渗透测试面试题总结-19(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
爱装代码的小瓶子6 小时前
【C++与Linux基础】进程间通讯方式:匿名管道
android·c++·后端
兴趣使然HX7 小时前
Android绘帧流程解析
android