横竖屏切换导致页面频繁重启?详细解读screenLayout

news2025/2/22 3:36:24

目录

  • 前言
  • configChanges
  • screenLayout
  • 平板问题
  • 总结

前言

前几天多名用户反馈同一个问题,在小新平板上无法上网课,点击上课按钮后就退回到首页了。了解了一下发现小新平板现在销量特别好,于是赶紧申请了一台测试机打算看看到底是什么问题。

最后发现是screenLayout的问题,在manifest中为需要横竖屏切换的Acitivty配置screenLayout即可,如下:

<activity android:name=".MainActivity"
  android:configChanges="orientation|keyboardHidden|screenSize|screenLayout"
    android:launchMode="singleTask">
    <intent-filter>
       ...
    </intent-filter>
</activity>

我们之前android:configChanges配置是orientation|keyboardHidden|screenSize,缺少了screenLayout。

但是为什么在其他设备上没问题,唯独在小新平板上有问题呢?而且为什么添加了screenLayout就解决问题了,这其中的原理是什么?我非常好奇,于是深入研究了一下。

configChanges

首先我们要知道android:configChanges这个配置的作用,这里我们来看看官方的介绍:

列出 Activity 将自行处理的配置变更。在运行时发生配置变更时,默认情况下会关闭 Activity 并将其重启,但使用该属性声明配置将阻止 Activity 重启。相反,Activity 会保持运行状态,并且系统会调用其 onConfigurationChanged() 方法。

当Activity的配置发生变更时(如横竖屏切换),如果在android:configChanges中没有添加该配置,那么就会关闭并重启Activity,这时候debug会发现重新执行了onCreate。但是当我们添加了该配置,如果该配置发生变更,则不会重启Activity,会调用onConfigurationChanged()方法。

最常用的配置如下:

  • orientation:就是对应着横竖屏切换
  • keyboardHidden:则是软键盘弹出
  • screenSize:则是屏幕尺寸改变。

这么来看我们设置了orientation应该就可以了,但是官方在这里有一个提示,如下:

2176C3C5-CF94-4185-86B0-F615141A5CB6.png

官方建议在设置orientation的同时设置screenSizescreenLayoutscreenSize我么可以理解,横竖屏切换时宽高会交换,那么screenLayout是指什么呢?

screenLayout

前面我们知道存在配置时会执行onConfigurationChanged(),这个函数的参数是Configuration类型的,这个类里保存着Activity的配置,我们来看看对screenLayout这个属性的描述:

/**  
Bit mask of overall layout of the screen. Currently there are four fields:

The SCREENLAYOUT_SIZE_MASK bits define the overall size of the screen. They may be one of SCREENLAYOUT_SIZE_SMALL, SCREENLAYOUT_SIZE_NORMAL,  SCREENLAYOUT_SIZE_LARGE, or SCREENLAYOUT_SIZE_XLARGE.

The SCREENLAYOUT_LONG_MASK defines whether the screen is wider/taller than normal.  They may be one of SCREENLAYOUT_LONG_NO or SCREENLAYOUT_LONG_YES.

The SCREENLAYOUT_LAYOUTDIR_MASK defines whether the screen layout is either LTR or RTL.  They may be one of SCREENLAYOUT_LAYOUTDIR_LTR or SCREENLAYOUT_LAYOUTDIR_RTL.

The SCREENLAYOUT_ROUND_MASK defines whether the screen has a rounded shape.  They may be one of SCREENLAYOUT_ROUND_NO or SCREENLAYOUT_ROUND_YES.

See Supporting Multiple Screens for more information.
**/  
public int screenLayout;

可以看到screenLayout其实是承载着四个配置的:

  1. 屏幕大小等级:有四种
    • SCREENLAYOUT_SIZE_SMALL
    • SCREENLAYOUT_SIZE_NORMAL
    • SCREENLAYOUT_SIZE_LARGE
    • SCREENLAYOUT_SIZE_XLARGE
  2. 是否宽屏:屏幕是否比普通屏幕更宽或更高
  3. 屏幕方向:屏幕是从左向右显示,还是从有向左显示
  4. 是否是圆角屏:屏幕是否有圆角

通过将screenLayout于对应mask进行与运算就可以得到当前屏幕在该属性的值,比如screenLayout & SCREENLAYOUT_SIZE_MASK

就可以得到屏幕大小等级,一定是SCREENLAYOUT_SIZE_SMALL, SCREENLAYOUT_SIZE_NORMAL,
SCREENLAYOUT_SIZE_LARGESCREENLAYOUT_SIZE_XLARGE之一。

四个mask对应的二进制分别是:

  • SCREENLAYOUT_SIZE_MASK: 0000 0000 1111
  • SCREENLAYOUT_LONG_MASK: 0000 0011 0000
  • SCREENLAYOUT_LAYOUTDIR_MASK:0000 1100 0000
  • SCREENLAYOUT_ROUND_MASK: 0011 0000 0000

比如在我的测试机上得到的screenLayout是268435810,转成二进制就是

0001 0000 0000 0000 0000 0001 0110 0010

通过与四个mask分别计算得到SCREENLAYOUT_SIZE_NORMAL、SCREENLAYOUT_LONG_NO、SCREENLAYOUT_LAYOUTDIR_LTR和SCREENLAYOUT_ROUND_NO

而且无论横屏还是竖屏,我的测试机的screenLayout是不变的,所以即使在android:configChanges中没用添加screenLayout,横竖屏切换的时候也不会重启Activity,因为其他两个属性orientationscreenSize都添加了。

平板问题

那么为什么小新平板上会有不同的现象,在android:configChanges中添加screenLayout完后我在onConfigurationChanged函数中debug获取screenLayout值,发现横屏和竖屏这个值是不同的,分别是268435812和268435796。

通过与mask运算获取四个属性后对比发现,横竖屏切换后SCREENLAYOUT_LONG_NO变成了SCREENLAYOUT_LONG_YES,所以没添加screenLayout的时候就会导致Activity重启,添加后就可以了。

至于为什么重启Activity会导致回退到首页,其实是用户表述问题,现象是应用重启了。为什么应用会重启,这是因为我们的应用架构是单Activity的,页面由fragment承载。当从详情页打开上课页面时,会通过代码手动将竖屏切换到横屏(同时为了返回详情页时换回竖屏,在详情页手动切换回竖屏)。这时候Activity重启并以横屏状态恢复所有fragment,但是恢复详情页时候,又切换到竖屏,所以又重启;然后以竖屏状态恢复到上课页面,又进行了切换,于是死循环,最后系统将应用重启。

总结

一直以来对android:configChanges没有太在意,正好趁着这个机会了解了一番,大家以后一定要注意这里,特别注意官方文档的提示,很重要。

推荐阅读:
详细解读Android中的事件分发机制

【Android开发】事件是如何分发到Activity的?

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

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

相关文章

牛客网语法篇刷题(C语言) — 分支控制

作者主页&#xff1a;paper jie的博客_CSDN博客-C语言,算法详解领域博主 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《C语言-语法篇》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白…

附录6-todolist案例

效果是这样的 可以添加新任务&#xff0c;改变任务状态&#xff0c;与筛选任务列表 使用vant创建的项目 使用到了bootstrap&#xff0c;首先 npm install bootstrap进行安装&#xff0c;安装后导入css与js 上中下是三个组件&#xff0c;依次是 todo_input&#xff0c;todo_li…

Python控制LitePoint IQxel-MW 无线网络测试仪

前言 由于项目需要进行WIFI和BT&#xff08;蓝牙&#xff09;的射频测试&#xff0c;所以需要开发一款支持WIFI/BT射频测试的工具。开发射频测试工具的话那肯定离不开仪表的控制。我们项目用的就Litepoint的IQxel-MW无线网络测试仪。这篇文章主要就是介绍一下如何控制仪表以及…

初探core组件:opencv - core组件进阶

core组件进阶 1.访问图像中的像素1.1 图像在内存之中的存储方式1.2 颜色空间缩减1.3 LUT函数&#xff1a;Look up table1.4 计时函数 2. ROI区域图像叠加&图像混合2.1 感兴趣区域&#xff1a;ROI2.2 ROI案例2.2 线性混合操作2.3 计算数组加权和&#xff1a;addWeighted()函…

python-segno:二维码制作

目录 二维码版本 微二维码、数据掩码、数据流、模式 微二维码 数据掩码 数据流 二维码模式 二维码背景 二维码参数 helpers方法 其他库制作及二维码读取&#xff1a;python生成和读取二维码_觅远的博客-CSDN博客 安装&#xff1a;pip install segno import segnoqr …

Qt+QtWebApp开发笔记(六):http服务器html实现静态相对路径调用第三方js文件

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/131244269 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

经典30个嵌入式面试问题

经典30个嵌入式面试问题 嵌入式系统的面试经典问题有很多&#xff0c;以下是其中的30个常见问题&#xff1a; 1. 什么是嵌入式系统&#xff1f; 2. 嵌入式系统和普通计算机系统有什么区别&#xff1f; 3. 嵌入式系统的主要应用领域有哪些&#xff1f; 4. 嵌入式系统的设计…

接口测试工具之postman

概念 接口测试是什么&#xff1f; 百度百科给出的解释是&#xff1a; 接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及系统间…

构造函数初始化列表的问题

构造函数初始化列表的问题 无法按照表达式中的算符来修改值原因基本原则由此引申的问题使用初始化列表对类成员初始化在构造函数中赋值对类成员初始化 针对构造函数传参,使用引用的情况使用初始化列表对类成员初始化在构造函数中赋值对类成员初始化 将属性也使用引用总结 无法按…

STM32开发——看门狗

目录 1.独立看门狗 1.1需求 1.2CubeMX设置 1.3函数代码 2.窗口看门狗 2.1需求 ​2.2WWDG配置&#xff1a; 2.3函数代码 3.独立看门狗和窗口看门狗的异同点 1.独立看门狗 监测单片机程序运行状态的模块或者芯片&#xff0c;俗称“看门狗”(watchdog) 。 独立看门狗本质 本…

6、DuiLib控件消息响应处理

文章目录 1、DuiLib控件消息响应处理2、基本的消息响应处理 Notify3、仿 MFC 形式消息响应 DUI_DECLARE_MESSAGE_MAP4、事件委托 MakeDelegate5、消息捕获&#xff08;拦截&#xff09;原生消息 HandleMessage 1、DuiLib控件消息响应处理 <?xml version"1.0" en…

软件测试基础教程学习3

文章目录 软件质量与测试3.1 软件质量问题的原因3.2 对软件质量特性的理解3.3 基于软件质量特性的测试3.4 软件能力成熟度模型&#xff08;CMM&#xff09; 软件质量与测试 3.1 软件质量问题的原因 软件质量问题的原因有以下几种&#xff1a; 软件本身的特点和目前普遍采用的…

AWTK实现汽车仪表Cluster/DashBoard嵌入式GUI开发(五):芯片型号

前言 随着汽车四化的推进,可以说汽车仪表也变成越来越智能化的一个ECU部件了。市面上的车型很多,油车发展了很多年,都有仪表,电车也发展起来了,车型也非常丰富,也都有仪表。仪表现在是作为多屏中一个屏存在的,现在车上最多的就是屏了,最大的要算中控屏了,有的还有空调…

【基础】MQTT -- MQTT 协议详解

【基础】MQTT -- MQTT协议详解 与 Broker 建立连接CONNECT 数据包CONNACK 数据包 断开连接DISCONNECT 数据包 订阅与发布PUBLISH 数据包SUBSCRIBE 数据包SUBACK 数据包UNSUBSCRIBE 数据包UNSUBACK 数据包 本文内容针对 MQTT 3.1.1 版本&#xff0c;从连接、发布与订阅等方面对协…

OpenCV做个熊猫表情

有的时候很想把一些有意思的图中的人脸做成熊猫表情&#xff0c;但是由于不太会ps&#xff0c;只能无奈放弃&#xff0c;so sad... 正好最近想了解下opencv的使用&#xff0c;那就先试试做个简单的熊猫表情生成器把~~ 思路就是&#xff0c;工具给两个参数&#xff0c;一个是人…

最小系统板STM32F103C8T6烧录程序指南

STM32F103C8T6烧录程序 【购买链接】&#xff1a;STM32F103C8T6最小系统板 方法一&#xff1a;使用SWD模式烧录 此时BOOT0 0&#xff0c;BOOT1 X&#xff08;任意&#xff09;&#xff0c;跳线帽接法如下图所示 接好后&#xff0c;若手边有STLINK的话&#xff0c;可以使用…

DAY25:二叉树(十五)修剪二叉搜索树+有序数组转换为二叉搜索树+二叉搜索树转化为累加树

文章目录 669.修剪二叉搜索树思路错误代码示例最开始的写法debug测试逻辑错误&#xff1a;需要两次递归的原因内存操作报错&#xff1a;操作了已经被删除的内存的指针&#xff08;力扣平台delete操作的问题&#xff0c;放IDE里就好了&#xff09;打日志debug示例 力扣平台delet…

高并发之限流-RateLimiter

背景 限流是保护高并发系统的三把利器之一&#xff0c;另外两个是缓存和降级。限流在很多场景中用来限制并发和请求量&#xff0c;比如说秒杀抢购&#xff0c;保护自身系统和下游系统不被巨型流量冲垮等。 限流的目的是通过对并发访问/请求进行限速或者一个时间窗口内的的请求进…

华为OD机试之 ABR 车路协同场景(Java源码)

ABR 车路协同场景 题目描述 数轴有两个点的序列 A{A1&#xff0c; A2, …, Am}和 B{B1, B2, ..., Bn}&#xff0c; Ai 和 Bj 均为正整数&#xff0c; A、 B 已经从小到大排好序&#xff0c; A、 B 均肯定不为空&#xff0c; 给定一个距离 R&#xff08;正整数&#xff09;&a…

一文详解!Selenium浏览器自动化测试框架

目录 前言&#xff1a; selenium简介 介绍 功能 优势 基本使用 获取单节点 获取多节点 节点交互 动作链 执行JavaScript代码 获取节点信息 切换frame 延时等待 前进和后退 cookies 选项卡管理 异常处理 选项卡切换 无头浏览器 前言&#xff1a; Selenium是…