首先放一张看了不知道多少次的图
Activity,android的四大组件之一(翻译为“活动”),你也可以理解为一个activity就是一个页面。
- onCreate:表示activity正在被创建,这是生命周期里的第一个方法,你在这个方法里可以做一下初始化的工作,譬如setContentView加载布局(创建视图),初始化变量,将数据绑定到视图列表之类。onCreate之后执行的就是onStart了。
- onRestart:表示activity正在重新启动,指的是activity从不可见到可见的状态,onRestart就会被调用,譬如我从页面A进到页面B,然后关闭了页面B回到页面A,那么这个时候A中的onRestart方法就会被调用。
- onStart:在onCreate或onReStart方法后执行,表示activity正在启动,《android开发艺术探索》中是这么介绍的,此时activity已经可见了但是没有出现在前台,还无法与用户交互,即activity已经显示出来了,但是我们还看不到。【1】
- onResume:activity处于前台(返回栈栈顶)并处于运行状态,此时可以进行交互。
- onPause:表示activity正在停止,正常情况下【2】onPause之后就会执行onStop了。这个时候可以做些存储数据,停止动画的操作,但是不能太耗时。
- onStop:表示activity即将停止,可以做一下稍微重量级的回收工作,但是同样不能太耗时。
- onDestroy:表示activity即将被销毁,这是生命周期的最后一步,这个时候我们可以做些资源释放跟回收的工作
【1】:关于显示出来了但是看不到这个问题,你可以看做这个activity已经创建好了,但是是处于后台的状态,甚至你可以理解为这是一个从未处于栈顶(处于后台)然后移到栈顶(前台)的过程;
【2】:“正常情况”这四个字圈起来,考试要考。既然有正常情况,那一定会有非正常情况咯,这边简单提下,具体实践大家自己去试试哈。Activity a跳到Activity b,设置b中的主题
android:theme="@android:style/Theme.Dialog"
或者
android:theme="@android:style/Theme.Translucent" //透明主题
此时a中的onStop方法是不会执行的,亦或者《android开发艺术探索》中提到,a跳到b,再快速回到a,那么a中的onStop方法还没来得及执行,就会去执行onResume
既然讲了每个方法代表的含义了,自然也是不能少了一番实践
当Activity刚启动的时候,会执行a中的生命周期如下:
onCreate->onStart->onResume;
当Activity a跳到其他页面,或者回到桌面(按home键),会执行a中的:
onPause->onStop(正常情况下)
再次回到a页面时,会执行a中的:
onRestart->onStart->onResume
退出a页面的时候,会执行a中的:
onPause->onStop->onDestory
Activity a =>Activity b 执行顺序:
onPause: A
onCreate: B
onStart: B
onResume: B
onStop: A
在这里面onCreate与onDestroy是配对的,分别标识着activity的创建与销毁,onStart与onStop是配对的,从activity是否可见来说,onResume与onPause是配对,从activity是否处于前台来说。(具体的为什么是这样的执行顺序大家有空可以去看看源码)
Activity的四大形态
Activity最大的特点就是可以拥有多种形态,它可以在多形态之间进行切换,以此来控制自己的生命周期
Active/Paused/Stopped/Killed
Activie:当前Activity正处于运行状态,指的是当前Activity获取了焦点。Paused:当前Activity正处于暂停状态,指的是当前Activity失去焦点,此时的Activity并没有被销毁,内存里面的成员变量,状态信息等仍然存在,当然这个Activity也仍然可见,但是焦点却不在它身上,比如被一个对话框形式的Activity获取了焦点,或者被一个透明的Activity获取了焦点,这都能导致当前的Activity处于paused状态。
Stopped:与paused状态相似,stopped状态的Activity是完全不可见的,但是内存里面的成员变量,状态信息等仍然存在,但是也没有被销毁。
Killed:已经被销毁的Activity才处于killed状态,它的内存里面的成员变量,状态信息等都会被一并回收。
四大状态转自:https://blog.csdn.net/clandellen/article/details/79257489
横竖屏生命周期切换
如果不设置configchanges这个属性的话,
竖屏切换到横屏 || 竖屏切换到横屏:
onPause
onStop
onDestroy
onCreate
onStart
onResume
无论横屏切换到竖屏,还是竖屏切换到横屏(360度都试过了),都只会执行一次“完整”的生命周期。
(PS :有一个有趣的现象,横竖屏旋转180°(手速快点,也不用太快),activity是不会被销毁重建的)
如果不想activity被销毁重建的话,就需要配置configchanges
这个属性,具体的属性如下:
属 性值 | 含 义 |
---|---|
mcc | SIM卡唯一标识IMSI(国际移动用户标识码)中的国家代码,由三位数字组成,中国为460 这里标识mcc代码发生了改变 |
mnc | SIM卡唯一标识IMSI(国际移动用户标识码)中的运营商代码,由两位数字组成,中国移动TD系统为00,中国联通为01,电信为03,此项标识mnc发生了改变 |
locale | 设备的本地位置发生了改变,一般指的是切换了系统语言 |
touchscreen | 触摸屏发生了改变,这个很费解,正常情况下无法发生,可以忽略它 |
keyboard | 键盘类型发生了改变,比如用户使用了外接键盘 |
keyboardHidden | 键盘的可访问性发生了改变,比如用户调出了键盘 |
navigation | 系统导航方式发生了改变,比如采用了轨迹球导航,正常情况下无法发生,可以忽略它 |
screenLayout | 屏幕布局发生了改变,很可能是用户激活了另外一个显示设备 |
fontScale | 系统字体缩放比例发生了改变,比如用户选择了个新的字号 |
uiMode | 用户界面模式发生了改变,比如是否开启了夜间模式(API 8新添加) |
orientation | 屏幕方向发生改变,这个是最常用的,比如旋转了手机屏幕 |
screenSize | 当屏幕尺寸信息发生改变,当旋转设备屏幕时,屏幕尺寸会发生变化,这个选项比较特殊,它和编译选项有关,当minSdkVersion和targetSdkVersion均低于13时,此选项不会导致Activity重启,否则会导致Activity重启(API 13新添加) |
smallestScreenSize | 设备的物理屏幕尺寸发生改变,这个属性和屏幕方向没关系,仅仅表示在实际的物理屏幕的尺寸改变的时候发生,比如切换到外部显示设备,它和编译选项有关,当minSdkVersion和targetSdkVersion均低于13时,此选项不会导致Activity重启,否则会导致Activity重启(API 13新添加) |
layoutDirection | 当布局方向发生改变的时候,这个属性用的比较少,正常情况下无法修改布局的layoutDirection的属性(API17新添加) |
--该表来自《android开发艺术探索》
那么根据上面的属性我们可以发现,只需要配置
android:configChanges="orientation|screenSize"
那么横竖屏切换的时候,activity就不会被销毁重建了(targetSdkVersion&&minSdkVersion>13)
<13只需要orientation
即可
设置横竖屏的方法:
java代码中:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//设置横屏
这个不是页面一进去就切换横竖屏,而是执行到这行代码的时候,再进行对应的横竖屏切换。
(题外话:有一次我在onCreate方法里执行这行代码切换横屏,并在该代码下方进行dialog的声明与网络请求,但是到了网络请求回调给我返回值,隐藏dialog的时候报了dialog空指针Nullexception的异常,猜测该方法不会阻断下面代码的执行,所以网络请求还是被执行了,回调回来的时候dialog还未被创建。真正的原因就得看下源码来判断了)
也可以在清单文件AndroidManifest.xml中配置
android:screenOrientation="portrait"//竖屏
android:screenOrientation="landscape"//横屏
本文总结于《android开发艺术探索》,基于android 9.0