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

相关推荐
Answer_momo13 小时前
一文读懂 Kotlin 数据流 Flow 的使用
android
雨白13 小时前
Kotlin Flow 入门:构建响应式异步数据流
android·kotlin
阿里云云原生13 小时前
告别手动埋点!Android 无侵入式数据采集方案深度解析
android·云原生
Tlaster14 小时前
使用KMP实现原生UI + Compose混合的社交客户端
android·ios·开源
袁煦丞 cpolar内网穿透实验室14 小时前
安卓旧机变服务器,KSWEB部署Typecho博客并实现远程访问:cpolar内网穿透实验室第645个成功挑战
android·运维·服务器·远程工作·内网穿透·cpolar
游戏开发爱好者815 小时前
iOS 26 App 查看电池寿命技巧,多工具组合实践指南
android·macos·ios·小程序·uni-app·cocoa·iphone
用户416596736935515 小时前
基于Jetpack Compose 实现列表嵌套滚动联动机制 (完整源码解析)
android
林栩link15 小时前
【车载Android】使用自定义插件实现多语言自动化适配
android
消失的旧时光-194319 小时前
Flutter 响应式 + Clean Architecture / MVU 模式 实战指南
android·flutter·架构
404未精通的狗20 小时前
(数据结构)栈和队列
android·数据结构