Android Activity生命周期及启动模式详解
Activity
生命生命周期
主要从两个方面来总结:
生命周期总览(自己画的图片,丑一些):
正常情况下的生命周期:
Activity的生命周期可以成对的来记忆:
1.onCreate
和onDestory
是一对,标识着Activity
的创建与销毁
2.onStart
和onStop
是一对,标识着Activity
的开始可见与不可见
3.onResume
和onPause
是一对,标识着Activity
是否有焦点,也是能否与用户进行交互
Activity
从启动到运行经过onCreate-->onStart()-->onResume
,onCreate
的时候不可见,到onStart
的时候Activity
已经是可见的了.- 当
Activity
失去焦点但是仍然可见的时候会调用onPause
(常见的情况是弹出Dialog
或者透明背景的Activity) , 打开新的Activity
或者回调桌面,Activit
y彻底不可见的时候回回调onStop
,打开新Activity
的流程如下: - 锁屏与解锁触发的是
onPause
方法,没有onStop
- 当前Activity执行的是
onPause-->onStop
,要启动的Activity
按正常的生命周期走,要注意的是只有当前Activity
回调onPause
结束之后才能启动另一个Activity
,所以应该尽量避免在onPause
内处理耗时任务 - 如果
Activity
从无焦点可见到有焦点可见(常见的情景是Dialog
消失),回调onResume
回到运行状态 Activity
从完全不可见的状态回到可见状态(回到原Activity
),调用的是onRestart-->onStart-->onResume
.前提是在onStop
之后未被系统回收,如果当前Activity
优先级较低内存不足时被系统回收,那么退回Activity
时会重新开始生命周期,即onCreate-->onStart-->onResume
- 从整个生命周期来说,
onCreate
和onDestory
是相对的,标志着Activity
的创建和销毁,onStart
和onStop
是相对的,标志着Activity
是否可见,onResume
和onPause
是相对的,标志着Activity
是否有焦点,或者理解为是否在前台 Activity
的启动流程概述
异常情况下的生命周期:
所谓异常情况,就是除了受用户操作所导致的生命周期方法调度之外的其他情况,主要有两类:
资源文件相关的系统配置发生改变的情况
这个分类下最典型的情况是屏幕翻转,至于为什么分到资源文件改变相关,只要知道
res
目录下有不同的图片和资源文件对应不同的屏幕分辨率就可以了,类似的横竖屏也是有不同的资源文件对应的,只不过大部分情况下我们是只写一套资源的,(例如Android
自带的侧滑菜单,竖屏模式下需要滑动才能显示,横屏模式下直接就显示在侧边,这就是横竖屏资源文件的应用之一),这类情况下的生命周期如下图所示:图上显示的只是一个大概的流程,表面了当遇到此类异常情况的时候
Activity
会回调onSaveInstance
方法来保存数据,然后Activity
销毁,但是会自动重新创建,然后恢复之前保存的数据,然后到达运行状态.其中有一些细节需要注意:遇到此类异常
Activity
被销毁的时候,onPause
,onStop
,onDestory
都会走一遍onSaveInstanceState
方法只会在异常情况下被调用,正常的用户操作是不会触发这一方法的onSaveInstanceState
方法的回调时机是不确定的,但一定是在onStop
之前,当然也是onDestory
之前,可能在onPause
之前也可能在onPause
之后onRestoreInstanceState
只会在异常情况下有数据保存的时候才会在启动过程中调用,而且一旦调用其中传的Bundle
对象一定是不为空的,类似的onCreate
中也有Bundle
对象,但是需要判空操作.- 当
Activity
异常保存数据的时候,其承载的View
也需要保存数据,具体的流程是
- 当Activity发生异常需要保存数据的时候,回调onSaveInstanceState方法,Activity会委托WIndow去保存数据,Window接到请求时会委托其顶级容器,顶层容器一一通知子View来保存数据,典型的委托思想.
资源文件变化所引起的生命周期变化其实是可以避免的,当资源文件变换的时候不想重新创建Activity
的时候可以给Activity
指定configuration
属性,具体的属性值标示如下
项目 | 含义 |
---|---|
mcc | SIM卡唯一标示IMSI中的国家代码,三位数字组成,次标示标示mcc代码发生改变(自己的理解是切换国家) |
mnc | SIM卡唯一标识IMSI的运营商代码,移动为00,联通为01,电信为03,此项标识标识mnc发生改变 |
locale | 设备的本地地址发生了改变,一般指切换了系统语言 |
touchscreen | 触摸屏发生了改变,正常情况下不会发生 |
keyboard | 键盘类型发生了改变,比如使用外接键盘 |
keyboardHidden | 键盘的可访问性发生了改变,比如调出了键盘 |
navigation | 系统导航方式发生了改变,比如使用轨迹球 |
screenLayout | 屏幕的布局发生了改变,比如使用了外接设备 |
fontScale | 系统字体的缩放比例发生了改变,比如更换了字体 |
uiMode | 用户界面模式发生了改变,比如说使用夜间模式 |
orientation | 屏幕方向发生了改变,最常用的之一 |
screenSize | 屏幕的尺寸信息发生改变,搭配orientation一起使用禁止屏幕旋转重走生命周期 |
smallesScreenSize | 屏幕尺寸发生改变,但是只针对物理屏幕尺寸,比如说切换到外接屏幕 |
layoutDirection | 布局发生改变,较少使用 |
使用方法举例,比如说忽略屏幕旋转时候的生命周期改变
<activity
...
android:configChanges = "orientation|screenSize"
...
...