Activity生命周期的全面分析

Activity生命周期的全面分析

Activity的生命周期分为两部分:典型情况下的生命周期和异常情况下的生命周期.
1. 典型情况下的生命周期
是指在有用户参与的情况下Activity所经过的生命周期的改变;
在正常情况下,Activity会经历如下生命周期:
1. onCreate —表示Activity正在被创建。这个生命周期的第一个方法,在该方法内我们主要处理一些初始化工作,如调用setContentView去加载布局资源和初始化Activity所需数据等
2. onRestart—表示Activity正在重新启动。一般情况下,当当前Activity由不可见重新变为可见状态时,onRestart就会被调用,这种情况一般是用户行为导致的。
3. onStart —表示Activity正在被启动,即将开始。这个时候Activity已经可见了,但是还没有出现在前台,无法与用户进行互动,即所谓的可见不可操作。
4. onResume—表示Activity已经可见,并且可以活动与用户进行互动了,与onStart的区别在于一个还在后台一个已经在前台了。
5. onPause—顾名思义,就是暂停状态,表示Activity正在停止,正常情况下,onStop会紧接着调用,在特殊情况下,如果这个时候快速的返回当前Activity,那么onResume会被调用,但这是一种极限条件,在这个阶段可以做一些数据的保存,但是需要注意的是不能够太耗时,因为这会影响到Activity的显示,onPause必须先执行完,新的Activity的onResume才会执行。
6. onStop —表示Activity即将停止,可以做一些重量级的回收工作,但是同样需要注意的是也不能够太耗时。
7. onDestroy—-表示Activity即将被销毁,这是Activity的最后一个生命周期,我们主要做一些回收工作和最终的资源释放。
最终:典型情况下的生命周期活动如下图:
Activity生命周期的全面分析_第1张图片
注意和说明:
1. 正当一个特点的Activity,第一次启动的回调如下:onCreate–>onStart—>onResume;
2. 当用户打开新的Activity或者切换到新的Activity时,回调如下:onPause—>onStop
有一种特殊情况就是,如果新的Activity设置了透明主题那么当前Activity不会回调onStop;
3. 当用户再次回到原Activity,回调如下:onRestart—>onStart—>onResume;
4. 当按back回退时,回调如下:onPause—>onStop—>ondestroy

2. 异常情况下的生命周期
是指Activity被系统回收或者由于当前设备的configuration发生改变而导致Activity被销毁重建,异常情况 下的生命周期的关注点和典型情况下的略有不同.
1. 情况1:资源相关的系统配置发生改变导致Activity被销毁并重建
在默认情况下,如果我们的Activity不做特殊处理,那么当系统配置大声改变后,Activity就会被销 毁重建,其生命周期如下:
Activity—–意外情况—>onSaveInsatanceState —>ondestroy;在这个过程中辉重建调用过程是Activity—>oncreate—>onRestoreInstanceState;
当系统配置发生改变后,Activity会被销毁,其onPause onStop ondestroy都会被调用,但由于是在异常情况下终止的,系统会调用onSaveInsatanceState 来保存当前Activtity的状态,这个方法是在onStop前调用的,但是它和onpause没有任何时序上的关联,它可能在onpause之前也可能在之后才调用,但需要强调的是它只有在Activity被异常终止的情况下才会调用,,并且在重新创建时调用onRestoreInstanceState方法,并且把Activity销毁时onSaveInsatanceState 保存的Bundle对象作为参数传递给onRestoreInstanceState和onCreate方法。我们可以通过这个参数来判断Activity是否被重建,如果重建了,我们可以取出其中的数据进行恢复。从时序上来说onRestoreInstanceState是在onstart后的。
那么具体系统会为我们保存哪些数据呢? 系统会默认为我们保存当前Activity的视图结构,并且在重建后为我们恢复这些数据,如文本框输出,listView滚动位置等,这些View相关的状态都会默认为我们保存,针对具体的一个特定的View系统能为我们保存哪些数据,需要去查看该View的onSaveInsatanceState onRestoreInstanceState的方法,查看其具体实现。
关于保存和恢复View层次结构,具体流程如下:首先Activity被意外终止,Activity会调用onSaveInsatanceState 去保存数据,然后Activity会委托Window去保存数据,接着Window在委托它上层的顶级容器去保存,顶级容器是一个Viewgroup,然后顶层容器再去一一通知它的子容器去保存数据,这样整个数据保存就完成了,这是一种典型的委托思想。
2. 资源内存不足导致优先级低的Activity被杀死
这种情况下的流程和情况一的启动流程一样,需要注意的是Activity的优先级和避免重建的方法。
首先说一下优先级,从高到低氛围如下三种
1.前台Activity—->正在和用户交互的Activity,优先级最高
2.可见但非前台Activity —->比如弹出对话框导致可见但是不是前台的无法与用户交互
3. 后台Activity —–>已经被暂停的Activity,比如执行了onStop方法,优先级最低。
当系统内存不足时,会根据Activity的优先级去杀死目标Activity所在的进程,并通过onSaveInsatanceState onRestoreInstanceState来存储和恢复数据。如果一个进程没有四大组在执行,那么这个进程很快就会被杀死。
当系统配置发生改变,Activity就会被销毁重建,那么有没有办法不重新创建呢?有,通过给Activity指定configChange属性。比如不想让Activity在频幕旋转时重建就可以给configChange设置Orientation这个值。系统配置所包含的项目是非常多的,包括了每个项目的含义:
mcc:The IMSI mobile country code (MCC) has changed — a SIM has been detected and updated the MCC.
IMSI(国际移动用户识别码)发生改变,检测到SIM卡,或者更新MCC
mnc:The IMSI mobile network code (MNC) has changed — a SIM has been detected and updated the MNC.
IMSI网络发生改变,检测到SIM卡,或者更新MCC
其中mcc和mnc理论上不可能发生变化
locale:The locale has changed — the user has selected a new language that text should be displayed in.
语言发生改变,用户选择了一个新的语言,文字应该重新显示
touchscreen:The touchscreen has changed. (This should never normally happen.)
触摸屏发生改变,这通常是不应该发生的
keyboard:The keyboard type has changed — for example, the user has plugged in an external keyboard.
键盘类型发生改变,例如,用户使用了外部键盘
keyboardHidden:The keyboard accessibility has changed — for example, the user has revealed the hardware keyboard.
键盘发生改变,例如,用户使用了硬件键盘
navigation:The navigation type (trackball/dpad) has changed. (This should never normally happen.)
导航发生改变,(这通常不应该发生) 举例:连接蓝牙键盘,连接后确实导致了navigation的类型发生变化。因为连接蓝牙键盘后,我可以使用方向键来navigate了
screenLayout:The screen layout has changed — this might be caused by a different display being activated.
屏幕的布局发生改变,这可能导致激活不同的显示
fontScale:The font scaling factor has changed — the user has selected a new global font size.
全局字体大小缩放发生改变
orientation:The screen orientation has changed — that is, the user has rotated the device.设备旋转,横向显示和竖向显示模式切换。
screenSize: 屏幕大小改变了
smallestScreenSize: 屏幕的物理大小改变了,如:连接到一个外部的屏幕上
4.2增加了一个layoutDirection属性,当改变语言设置后,该属性也会成newConfig中的一个mask位。所以ActivityManagerService(实际在ActivityStack)在决定是否重启Activity的时候总是判断为重启。
需要在android:configChanges 中同时添加locale和layoutDirection。
在不退出应用的情况下切换到Settings里切换语言,发现该Activity还是重启了。

你可能感兴趣的:(android,生命周期)