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

相关推荐
野生的码农17 小时前
放过自己,降低预期,及时行乐
android·ai编程
huwuhang18 小时前
索尼PS3游戏合集【中文游戏】8.12T 1430个游戏+PS3模拟器
android·游戏·智能手机·游戏机·电视
Grackers20 小时前
Android Perfetto 系列 5:Android App 基于 Choreographer 的渲染流程
android
踩着两条虫20 小时前
AI驱动的Vue3应用开发平台深入探究(十):物料系统之内置组件库
android·前端·vue.js·人工智能·低代码·系统架构·rxjava
sam.li20 小时前
JADX MCP 原理与使用部署
android·逆向·jadx
冬奇Lab20 小时前
Android 15音频子系统(五):AudioPolicyService策略管理深度解析
android·音视频开发·源码阅读
亚历克斯神21 小时前
Flutter for OpenHarmony: Flutter 三方库 mutex 为鸿蒙异步任务提供可靠的临界资源互斥锁(并发安全基石)
android·数据库·安全·flutter·华为·harmonyos
dalancon1 天前
SurfaceControl 的事务提交给 SurfaceFlinger,以及 SurfaceFlinger 如何将这些数据设置到对应 Layer 的完整流程
android
dalancon1 天前
SurfaceFlinger Layer 到 HWC 通信流程详解
android
cccccc语言我来了1 天前
Linux(9)操作系统
android·java·linux