android之activity横竖屏切换时的生命周期以及横竖屏切换时的资源适配方案

背景:之前有过两篇写activity的博客android之activity的生命周期详解:详细介绍了activity的整个生命周期、各状态间的转换和返回桌面时保存activity的状态android之activity中onSaveInstanceState和onRestoreInstanceState的触发时机:介绍了activity中这两个方法的触发时机和作用本篇博客会牵扯到里面的内容,如果你都

大家好,又见面了,我是全栈君。

背景:之前有过两篇写activity的博客

android之activity的生命周期详解:详细介绍了activity的整个生命周期、各状态间的转换和返回桌面时保存activity的状态

android之activity中onSaveInstanceState和onRestoreInstanceState的触发时机:介绍了activity中这两个方法的触发时机和作用

本篇博客会牵扯到里面的内容,如果你都有所了解可以直接往下看,如果不了解可以进去回忆下。

问题:在做应用的退出对话框时,发现如果对话框弹出,然后把手机横竖屏切换一下,对话框就消失了。知道activity在横竖屏切换时会走一些生命周期,就误以为是在onPause和onResume的时候没有把对话框恢复出来,

首先想到就是设一个全局变量isDialogShow用来保存对话框是否显示,在onPause中检查下如果显示了,就把isDialogShow设置为true,然后在onResume中判断下isDialogShow的值,如果为true,则把对话框在显示出来。

以为这样就解决了,运行发现不对,对话框还是不显示。

然后debug发现,每次进入onResume的时候,isDialogShow都是false,也就是说每次isDialogShow都被重新初始化了。

这时候才突然意识到,横竖屏切换的时候生命周期可能不是我想的那样。

就借着这个机会去总结一下activity横竖屏切换时如何保存状态以及自适应布局。

解决方案对于这个问题,有三种方案

1⃣️顺应activity的生命周期,保存然后恢复状态,onCreate中动态适应布局。

2⃣️在AndroidManifest.xml中设置,不让activity重走生命周期从而保存状态,通过onConfigurationChanged自适应布局或者setRequestedOrientation手动设置横竖屏,此时activity的生命周期是不会重走的

3⃣️禁止activity的横竖屏转换,状态和布局保持原样。

方案一

首先把activity的每个方法打印出来。

启动应用(此时是竖屏):

android之activity横竖屏切换时的生命周期以及横竖屏切换时的资源适配方案

切换为横屏:

       android之activity横竖屏切换时的生命周期以及横竖屏切换时的资源适配方案

里面的数字是加的一个全局变量(初始化为0,每进入一次onPause自动加1),用来看数值的变化,可见在onPause的时候还是1,等切换完成再回来的时候就成了0了。

也很容易理解,activity相当于完全重新做了一次初始化,完整走了一遍生命周期。

同时也注意到,切换为横屏的时候多了onSaveInstanceState和onRestoreInstanceState方法,上面第二篇博客里面说到的,activity在有“被销毁的可能”时,就会调用onSaveInstanceState方法,给你一个机会去保存activity中的数据,之后横竖屏切换时activity确实在“未经你许可的情况下被销毁了”,所以系统又会调用onRestoreInstanceState方法,让你把之前保存的数据恢复。

所以这样就明白了为什么我的对话框切换横竖屏之后不出来,而且用来记录的isDialogShow的值会被重置,如此解决方案也有了。

onSaveInstanceState方法中保存isDialogShow的值,然后在onRestoreInstanceState方法中取回isDialogShow 的值,去判断该不该显示对话框就可以了。

那么如何自适应布局呢,像xml之类的资源,只要建两套就可以了,横屏资源放在res/layout-land里面,竖屏资源放在res/layout-port文件夹里面,资源名字都一样即可,系统会自己去找。

也可以通过以下方法获取目前横竖屏状态分别实现一些资源的加载。

if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
 //do something
} else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
 //do something
}

以上就完成了在activity的完整生命周期里面保存状态以及自适应资源。



方案二

在说方案二的时候要提一下,既然可以避免activity重新走生命周期,为什么还要设计这个横竖屏切换的时候去完整的重新走一遍生命周期呢?

因为既然手机切换了横竖屏,比如从竖屏切换为横屏了,那么原来竖屏的layout,drawable等资源可能无法适应横屏模式,设计完善的应用一般是会有两套资源来适配横竖屏模式的,所以在切换后重启activity,在新的创建过程中就会自

动使用横屏的资源,实现了动态适应。

方案二只需要在manifest文件中的activity标签下加如下代码

android:configChanges=”orientation”

这段代码的含义是向系统说明,这个activity的orientation发生变化时,我不需要你去自适应,我自己会在onConfigurationChanged方法中做处理或者说我自己完成横竖屏切换的适应,即告诉activity不要重新走生命周期,放着我来。

加上这个代码声明之后,重新运行会发现,activity的生命周期没有出现,只出现了一个方法就是

android之activity横竖屏切换时的生命周期以及横竖屏切换时的资源适配方案

那么切换过程中你要如何处理就是你自己的事情了,状态无需保存,都还是原来的,如果要做一些切换的话,可以通过如下代码获取到当前的横竖屏状态,然后自己操作。

if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
 // do something
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
 // do something
}

如果只是加下面这个的话,你会发现activity还是会走完整的生命周期,onConfigurationChanged方法压根不会执行

android:configChanges=”orientation”

这是因为从Android 3.2(API 13)开始,横竖屏切换时不仅orientation会发生变化,screenSize也会跟着发生变化,所以要改成下面这样。
android:configChanges=”orientation|screenSize”
告诉activity,不管是orientation变化还是screenSize变化,都不要重新初始化,都通过onConfigurationChanged让我自己操作。

以上就是不让activity重新初始化,而是自己完成横竖屏切换的自适应操作。

方案三

最简单最粗暴,禁止横竖屏转换,直接固定为横屏或者竖屏。

可以在配置Activity的地方进行如下的配置

android:screenOrientation="portrait"
android:screenOrientation="landscape" 

或者在onCreate里面

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
or
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

这样就可以保证是竖屏总是竖屏了,或者横屏总是横屏。

以上,就不涉及状态保存和布局适应了,不管横屏竖屏一切如初。

参考:

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1106/516.html

http://blog.csdn.net/aliang775/article/details/8561075

作者:jason0539

微博:http://weibo.com/2553717707

博客:http://blog.csdn.net/jason0539(转载请说明出处)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/121334.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 示波器中的trigger是什么意思_示波器中扫描和同步的作用是什么

    示波器中的trigger是什么意思_示波器中扫描和同步的作用是什么什么是Trigger,它在示波器中的作用是什么?先来看看别人是怎么说的。Thetriggereventestablishesthetime-referencepointinthewaveformrecord.Allwaveformrecorddataislocatedintimewithrespecttothatpoint.Theinstru…

    2022年10月11日
  • linux查看cpu核数和内存大小_查看linux内核参数

    linux查看cpu核数和内存大小_查看linux内核参数在linux系统中,提供了proc系统显示系统的软硬件信息,可以使用命令cat/proc/cpuinfo来查看1.查看物理CPU个数cat/proc/cpuinfo|grep”physicalid”|sort|uniq|wc-l2.查看每个物理CPU中core的个数(即核数)cat/proc/cpuinfo|grep”cpucores”|uniq3查看逻辑CPU的个数cat/proc/cpuinfo|grep”processor”|wc-..

    2022年10月26日
  • 设计模式(五)适配器模式Adapter(结构型)

    设计模式(五)适配器模式Adapter(结构型)设计模式(五)适配器模式Adapter(结构型)1.概述:接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题。程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相关库的发展和进化。例子1:iphone4,你即可以使用UBS接口连接电脑来充电,假如只有iphone没有电脑,怎么办呢?苹果提供了iphone电源适配器。………

  • 【javascript】使用happypack和thread-loader加速构建「建议收藏」

    【javascript】使用happypack和thread-loader加速构建「建议收藏」使用happypack/thread-loader加速构建标签:webpack为什么需要happypack/threadloader webpack需要处理的文件是非常多的,构建过程是一个涉及大量文件读写的过程。项目复杂起来了,文件数量变多之后,webpack构建就会特别满,而且运行在nodeJS上的webpack是单线程模型的,也就是说Webpack一个时刻只能处理一个任务,不能同时…

  • 别怕,“卷积“其实很简单

    别怕,“卷积“其实很简单我的机器学习教程「美团」算法工程师带你入门机器学习已经开始更新了,欢迎大家订阅~任何关于算法、编程、AI行业知识或博客内容的问题,可以随时扫码关注公众号「图灵的猫」,加入”学习小组“,沙雕博主在线答疑~此外,公众号内还有更多AI、算法、编程和大数据知识分享,以及免费的SSR节点和学习资料。其他平台(知乎/B站)也是同名「图灵的猫」,不要迷路哦~前言相信很多时候,当我们在…

  • 织梦CMS首页调用分类信息栏目及列表方法

    织梦CMS首页调用分类信息栏目及列表方法

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号