Android 8.0系统透明主题闪退解决办法

当Android当activity同时满足以下三个条件,会出现闪退当问题

1.Android系统8.0

2.透明主题

3.固定屏幕方向,screenOrientation的值为portrait 或者 landscape(代码或者清单文件)

错误信息:java.lang.IllegalStateException: Only fullscreen activities can request orientation

解决方案:

1.最暴力到方法就是回退sdk版本,sdk 26及以下

2.去除主题中的透明属性

例如:将android:windowIsTranslucent设置为false

3.指定除8.0以外的系统固定屏幕方向:

    去掉清单文件中screenOrientation属性,activity中onCreate中执行屏幕方向固定的代码    

if (android.os.Build.VERSION.SDK_INT != android.os.Build.VERSION_CODES.O) {
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
      //setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);  
} 

4.如果你前一个页面和需要透明主题的界面屏幕方向一致,我们只需要在清单文件中配置android:screenOrientation="behind",behind的意思就是和之前页面的屏幕方向保持一致。

5.通过反射,让系统绕过屏幕方向的检测,设置屏幕不固定

/**
 * @description: 修复android 8报错:Only fullscreen opaque activities can request orientation
 * 透明主题的 Activity,一般在以下2个场景中会出现闪退:
 *
 * 1、在 AndroidManfest.xml 中有 android:screenOrientation="portrait" 之类的配置;
 * 2、代码中调用 setRequestedOrientation(int orientation) 方法设置横竖屏方向;
 *
 * @date :2022/10/27 14:43
 */
public class FixAndroid8FixOrientationBug {
    /**
     * 在activity onCreate中调用,且早于父类的onCreate调用
     * @param act
     */
    public static void needFixAndroid8Bug(Activity act) {
        //如果是8.0系统的手机,并且认为是透明或者悬浮主题的Activity
        if (Build.VERSION.SDK_INT == 26 && isTranslucentOrFloating(act)) {
            //通过反射取消方向的设置,这样绕开系统的检查,避免闪退
            fixOrientation(act);
        }
    }

    //通过反射判断是否是透明页面
    private  static boolean isTranslucentOrFloating(Activity act) {
        boolean isTranslucentOrFloating = false;
        try {
            int[] styleableRes = (int[]) Class.forName("com.android.internal.R$styleable").getField("Window").get(null);
            final TypedArray ta = act.obtainStyledAttributes(styleableRes);
            Method m = ActivityInfo.class.getMethod("isTranslucentOrFloating", TypedArray.class);
            m.setAccessible(true);
            isTranslucentOrFloating = (boolean) m.invoke(null, ta);
            m.setAccessible(false);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return isTranslucentOrFloating;
    }

    //通过反射将方向设置为 SCREEN_ORIENTATION_UNSPECIFIED,绕开系统的检查
    private static boolean fixOrientation(Activity act) {
        try {
            Field field = Activity.class.getDeclaredField("mActivityInfo");
            field.setAccessible(true);
            ActivityInfo o = (ActivityInfo) field.get(act);
            o.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
            field.setAccessible(false);
            return true;
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return false;
    }
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值