Only fullscreen opaque activities can request orientation

news2024/9/23 17:24:36

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。
未经允许不得转载

目录

  • 一、导读
  • 二、概览
  • 三、分析
  • 四、 推荐阅读

在这里插入图片描述

一、导读

我们继续总结学习基础知识,温故知新。

本文记录一次bug解决的过程,

Only fullscreen opaque activities can request orientation

二、概览

今天将 targetSdkVersion 的版升级到了29,出现了一些奇怪的报错,日志如下


# main(1)

java.lang.IllegalStateException

Only fullscreen opaque activities can request orientation

解析原始
java.lang.RuntimeException:Unable to start activity ComponentInfo{com.xxx/com.xyz.QActivity}: java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3303)
......
Caused by:
java.lang.IllegalStateException:Only fullscreen opaque activities can request orientation
android.app.Activity.onCreate(Activity.java:10811)
androidx.core.app.ComponentActivity.void onCreate(android.os.Bundle)(ComponentActivity.java:861)
androidx.activity.ComponentActivity.void onCreate(android.os.Bundle)(ComponentActivity.java:3231)
androidx.fragment.app.FragmentActivity.void onCreate(android.os.Bundle)(FragmentActivity.java:2731)
com.xyz.QActivity.void onCreate(android.os.Bundle)(QActivity.java:518)
android.app.Activity.performCreate(Activity.java:7383)
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:11218)
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:31256)
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:31411)
android.app.ActivityThread.-wrap12(Unknown Source:0)
android.app.ActivityThread$H.handleMessage(ActivityThread.java:19194)
android.os.Handler.dispatchMessage(Handler.java:1018)
android.os.Looper.loop(Looper.java:166)
android.app.ActivityThread.main(ActivityThread.java:75129)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:2145)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:9211)

这个问题只有8。0的系统才会出现,下面我们一起来分析下原因。

三、分析

报的错误是只有全屏不透明的activity可以设置屏幕方向,那我们先看看activit的设置

    <activity
        android:name="com.xyz.QActivity"
        android:launchMode="singleTop"
        android:screenOrientation="portrait"           设置方向
        android:theme="@style/TransparentTheme" />     透明主题

以上我们设置了两个属性,我们再来看看源码,为什么8.0会报错

protected void onCreate(@Nullable Bundle savedInstanceState) {
 
    // 在 onCreate() 方法中会进行屏幕配置检查
    // 如果固定屏幕方向,且设置了透明色或者悬浮,则会抛出异常
    if (getApplicationInfo().targetSdkVersion > O && mActivityInfo.isFixedOrientation()) {
         if (isTranslucentOrFloating) {
             throw new IllegalStateException(
                        "Only fullscreen opaque activities can request orientation");
         }
    }
    //....
} 
 
 
//ActivityInfo.java
/**
 * 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;
}

知道了原因,我们来看看怎么解决问题,其思路是这样的,

  1. 检查是否透明色或者悬浮
  2. 如果有的话就设置屏幕不固定

说大白话就是进onCreate的时候,判断是透明窗口风格,把屏幕朝向改为未指定类型SCREEN_ORIENTATION_UNSPECIFIED,
因为Activity是透明的,所以其方向依赖于父Activity,所以这个改动对结果不会产生任何影响。

那我们怎么判断是否透明呢?答案是反射ActivityInfo,获取isTranslucentOrFloating的返回值,


    private boolean isTranslucentOrFloating() {
        boolean isTranslucentOrFloating = false;
        try {
            int[] styleableRes = (int[]) Class.forName("com.android.internal.R$styleable").getField("Window").get(null);
            final TypedArray ta = obtainStyledAttributes(styleableRes);
            Method m = ActivityInfo.class.getMethod("isTranslucentOrFloating", TypedArray.class);
            m.setAccessible(true);
            isTranslucentOrFloating = (boolean) m.invoke(null, ta);
            ta.recycle();
            m.setAccessible(false);
        } catch (Exception e) {
        }
        return isTranslucentOrFloating;
    }

那怎么设置方向呢?,答案还是反射


/**
 *  反射
 **/
    private static void fixOrientation(Activity activity) {
        
        try {
		
            Class activityClass = Activity.class;
            Field mActivityInfoField = activityClass.getDeclaredField("mActivityInfo");
            mActivityInfoField.setAccessible(true);
            
            ActivityInfo activityInfo = (ActivityInfo) mActivityInfoField.get(activity);
            
			// 获取activity 方向是否是固定的
            Method isFixedOrientation = ActivityInfo.class.getMethod("isFixedOrientation");
            isFixedOrientation.setAccessible(true);
            
			// 获取方法的值,即 源码中隐藏的方法 isFixedOrientation()
            boolean hasFixedOri = (boolean) isFixedOrientation.invoke(activityInfo);
            
            isFixedOrientation.setAccessible(false);
			
			// 如果是固定方向
            if (hasFixedOri) { // 当然我们也可以把判断过程去掉
                //设置屏幕不固定
                activityInfo.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_BEHIND;
            } else{
			    // do nothing
			}
			
            mActivityInfoField.setAccessible(false);
        } catch (Exception e) {
        }
		
		
        try {
            Class activityClass = Activity.class;
            Field mActivityInfoField = activityClass.getDeclaredField("mActivityInfo");
            mActivityInfoField.setAccessible(true);
            
            ActivityInfo activityInfo = (ActivityInfo) mActivityInfoField.get(activity);
            //设置屏幕不固定
            activityInfo.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
        } catch (Exception e) {
        }  
    }
	
	
	下面这个是源码
    /**
     * Returns true if the activity's orientation is fixed.
     * @hide
     */
    public boolean isFixedOrientation() {
        return isFixedOrientationLandscape() || isFixedOrientationPortrait()
                || screenOrientation == SCREEN_ORIENTATION_LOCKED;
    }

当然,我们还需要进行一次版本的判断


@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    //切记:在父类oncreate()方法调用前调用该方法修改配置
    if (Build.VERSION.SDK_INT == 26 && isTranslucentOrFloating()) {
        fixOrientation(this);
    }
    super.onCreate(savedInstanceState);
}

@Override
protected void setRequestedOrientation(int requestedOrientation) {
    // 这里也最好改下,最好是不要让主动进行设置
    if (Build.VERSION.SDK_INT == 26 && isTranslucentOrFloating()) {
        return;
    }
}

另外, Orientation 新增了已个behind属性,表示当前的Activity和栈中在它下方的Activity使用相同的方向。建议这里也改一下。

    <activity
        android:name="com.xyz.QActivity"
        android:launchMode="singleTop"
        android:screenOrientation="behind"           设置方向
        android:theme="@style/TransparentTheme" />     透明主题

四、 推荐阅读

Java 专栏

SQL 专栏

数据结构与算法

Android学习专栏

未经允许不得转载

ddd

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1502739.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【电工学笔记】上册第一、二章

电工学 上次考试败在了单位&#xff0c;这次单位 一定要记熟。 第一章 电源或信号源的电压或电流称为激励,它推动电路工作; 由激励所产生的电压和电流称为响应。 复杂电路中,一般无法事先判断某个支路电流的 实际方向或者某个电路元件电压的实际方向 140V/4算不出总电阻的 …

leetcode26---删除有序数组中的重复项

大家好&#xff0c;我是大唐&#xff0c;刚刷完了几道经典的leetcode题&#xff0c;今天给大家分享一道leetcode上面的快慢指针经典题型---删除有序数组中的重复项&#xff0c;我们往下看。 题目描述 给你一个 非严格递增排列 的数组 nums &#xff0c;请你原地删除重复出现的元…

【数据结构】拆分详解 - 排序

文章目录 前言一、排序的概念及其运用  1.1 排序的概念  1.2 排序的运用  1.3 常见的排序算法  1.4 排序算法性能测试对比函数 二、常见排序算法的实现  2.1 插入排序   2.1.1  基本思想   2.1.2  直接插入排序   2.1.3  希尔排序     1. 预排序&am…

Dataset 读取数据

Dataset 读取数据 from torch.utils.data import Dataset from PIL import Image import osclass Mydata(Dataset):def __init__(self,root_dir,label_dir):self.root_dir root_dir #根目录 dataset/trainself.label_dir label_dir #标签的后面链接目录 ants_ima…

ChatGPT 提问没反应了,怎么办?4种方法!试试看

用了将近 1 年的 ChatGPT 昨天下午提问忽然之间没反应了&#xff0c;有点失落&#xff0c;我原本以为是账号到期了呢。 之后&#xff0c;尝试用谷歌邮箱注册登录也不行。 打开调试一看&#xff0c;接口状态 403 &#xff0c;没有权限了&#xff0c;logout。 怎么办呢&#xf…

2023年12月CCF-GESP编程能力等级认证Python编程七级真题解析

本文收录于专栏《Python等级认证CCF-GESP真题解析》,专栏总目录・点这里 一、单选题(每题 2 分,共 30 分) 第1题 假设变量 x 为 float 类型,如果下面代码输入为 100,输出最接近( )。 A.0 B.-5 C.-8 D.8 答案:B 第2题 对于下面动态规划方法实现的函数,以下选项中…

【Nestjs实操】服务依赖注入

在开始学习之前&#xff0c;我们首先准备下开发环境&#xff1a; Node&#xff1a;16.20.2包管理器&#xff1a;pnpmnestjs版本&#xff1a;10.2.1全局安装nestjs命令行&#xff1a;pnpm add -g nestjs/cli 一、初始化项目 执行nest new nestjs-blog&#xff0c;系统会自动创…

关于 JVM

1、请你谈谈你对JVM的理解&#xff1f; JVM由JVM运行时数据区&#xff08;图示中蓝色框包含部分&#xff09;、执行引擎、本地库接口、本地方法库组成。 JVM运行时数据区&#xff0c;分为方法区、堆、虚拟机栈、本地方法栈和程序计数器。 1.方法区 Java 虚拟机规范中定…

黑马点评-异步秒杀实现

异步秒杀思路 我们来回顾一下下单流程 当用户发起请求&#xff0c;此时会请求nginx&#xff0c;nginx会访问到tomcat&#xff0c;而tomcat中的程序&#xff0c;会进行串行操作&#xff0c;分成如下几个步骤 1、查询优惠卷 2、判断秒杀库存是否足够 3、查询订单 4、校验是…

Draco点云压缩测试

ref&#xff1a;https://github.com/google/dracohttps://codelabs.developers.google.com/codelabs/draco-3d/index.html#6 Draco Draco 是一个用于编码压缩和解压缩 3D 几何网格和点云的库&#xff0c;从而改进 3D 图形的存储和传输该代码支持压缩点、连接信息、纹理坐标、颜…

个人代码分享(底层模板函数和三大模板)2024.3.6

源码&#xff1a;&#xff08;百度网盘&#xff09; 链接&#xff1a;https://pan.baidu.com/s/1jdfrQOGCWJaQgSUPEWcfdw?pwd1234 提取码&#xff1a;1234 说明&#xff1a; 从复习到应用所有学到的东西去做真题&#xff0c;笔者对于之前发过的文章里面的代码有着很多改动&…

用msvc编译器的cl.exe将gcc编译器的.s汇编文件转masm编译器的.asm文件

用msvc编译器的cl.exe将gcc编译器的.s汇编文件转masm编译器的.asm文件 cl /nologo /X /II:/code/reactos-master/sdk/include/asm /II:/code/reactos-master/output-VS-amd64-sln/sdk/include/asm -II:/code/reactos-master/sdk/include -II:/code/reactos-master/sdk/include…

051-WEB攻防-前后台功能点文件下载文件读取文件删除目录遍历目录穿越

051-WEB攻防-前后台功能点&文件下载&文件读取&文件删除&目录遍历&目录穿越 #知识点&#xff1a; 1、文件安全-前后台功能点-下载&读取&删除 2、目录安全-前后台功能点-目录遍历&目录穿越 演示案例&#xff1a; ➢文件安全-下载&删除-案例…

Centos 安装 redis【最简单】

Centos7 使⽤ yum 安装 ⾸先安装 scl 源, 再安装 redis &#xff08;因为 Centos7 yum 提供的软件包只有 3.0 版本的 Redis &#xff0c;太老了&#xff0c;我们要安装 redis 5 系列的&#xff09; yum install centos-release-scl-rh yum install rh-redis5-redis 创建符号…

阿里云99计划优惠:云服务器租用价格61元、99元、165元

阿里云99计划还有谁不知道么&#xff1f;阿里云不杀熟&#xff0c;新老用户同享&#xff0c;阿里云服务器99元一年&#xff0c;续费也是99元&#xff0c;续费不涨价家人们&#xff0c;2024年阿里云把云服务器价格打下来了&#xff0c;2核2G、2核4G、4核8G、4核16G、8核16G、8核…

《在“裸奔”时代下如何保护网络隐私》

引言 在信息时代的今天,网络已经成为我们生活中不可或缺的一部分。然而,随着网络的普及和技术的发展,网络安全和隐私保护问题也变得越来越严峻。特别是在这个所谓的“裸奔”时代,我们的个人信息和隐私正面临着前所未有的挑战。因此,保护网络隐私变得尤为重要。 网络安全…

吴恩达deeplearning.ai:机器学习的开发过程与优化方法

以下内容有任何不理解可以翻看我之前的博客哦&#xff1a;吴恩达deeplearning.ai专栏 我想在接下来分析下开发机器学习系统的过程&#xff0c;这样当你自己动手时&#xff0c;能够做出更加正确的判断。 机器学习开发的迭代 Iterative loop of ML development 决定模型架构 第…

flink实战--Flink任务资源自动化优化

背景 在生产环境Flink任务资源是用户在实时平台端进行配置,用户本身对于实时任务具体配置多少资源经验较少,所以存在用户资源配置较多,但实际使用不到的情形。比如一个 Flink 任务实际上 4 个并发能够满足业务处理需求,结果用户配置了 16 个并发,这种情况会导致实时计算资…

【uniapp】uniapp小程序中实现拍照同时打开闪光灯的功能,拍照闪光灯实现

一、需求前提 特殊场景中&#xff0c;需要拍照的同时打开闪光灯&#xff0c;&#xff08;例如黑暗场景下的设备维护巡检功能&#xff09;。 起初我是用的uviewui中的u-upload组件自带的拍照功能&#xff0c;但是这个不支持拍照时打开闪光灯&#xff0c;也不支持从通知栏中打开…

哈希表应用

例题 在这里使用一个简化版的问题进行分析&#xff1a;给定N个自然数&#xff0c;值域是&#xff0c;求出这N个自然数中共有多少个不同的自然数。 分析 如果值域是&#xff0c;那么可以利用之前介绍过的计数排序算法解决问题。定义一个的大数组a&#xff0c;每个位置a[x]所对…