Activity 之生命周期
本文内容:
1. Activity 介绍
2. Activity 的生命周期
2.1 生命周期图
2.2 常见状况下生命周期的回调
2.3 关于生命周期常见问题
2.4 异常状态下活动的生命周期
2.4.1 资源配置改变致使 Activity 重建
2.4.2 低优先级 Activity 因为内存不足被杀死
2.5 异常状况下的处理
2.5.1 数据保存
2.5.2 防止重建
3. 关于 Activity 的不经常使用的回调方法
3.1 onPostCreate()
3.2 onPostResume()
3.3 onContentChanged()
3.4 onUserInteraction()
3.5 onUserLeaveHint()
1. Activity 介绍
Activity 是 Android 的四大组件之一,主要用于提供窗口与用户进行交互。html
2. Activity 的生命周期
2.1 生命周期图
官网的 Activity 的生命周期图:
android
解释图中个方法的做用:web
生命周期方法 |
做用 |
说明 |
onCreate |
表示 Activity 正在被建立 |
activity 被建立时调用,通常在这个方法中进行活动的初始化工做,如设置布局工做、加载数据、绑定控件等。 |
onRestart |
表示 Activity 正在从新启动 |
这个回调表明了 Activity 由彻底不可见从新变为可见的过程,当 Activity 经历了 onStop() 回调变为彻底不可见后,若是用户返回原 Activity,便会触发该回调,而且紧接着会触发 onStart() 来使活动从新可见。 |
onStart |
表示 Activity 正在被启动 |
经历该回调后,Activity 由不可见变为可见,但此时处于后台可见,还不能和用户进行交互。 |
onResume |
表示 Activity 已经可见 |
已经可见的 Activity 从后台来到前台,能够和用户进行交互。 |
onPause |
表示 Activity 正在中止 |
当用户启动了新的 Activity ,原来的 Activity 再也不处于前台,也没法与用户进行交互,而且紧接着就会调用 onStop() 方法,但若是用户这时马上按返回键回到原 Activity ,就会调用 onResume() 方法让活动从新回到前台。并且在官方文档中给出了说明,不容许在 onPause() 方法中执行耗时操做,由于这会影响到新 Activity 的启动。 |
onStop |
表示 Activity 即将中止 |
这个回调表明了 Activity 由可见变为彻底不可见,在这里能够进行一些稍微重量级的操做。须要注意的是,处于 onPause() 和 onStop() 回调后的 Activity 优先级很低,当有优先级更高的应用须要内存时,该应用就会被杀死,那么当再次返回原 Activity 的时候,会从新调用 Activity 的onCreate()方法。 |
onDestroy |
表示 Activity 即将被销毁 |
来到了这个回调,说明 Activity 即将被销毁,应该将资源的回收和释放工做在该方法中执行。 |
2.2 常见状况下生命周期的回调
(A 与 B 表示不一样的 Activity )框架
状况 |
回调 |
第一次启动 |
onCreate() -> onStart() -> onResume() |
从 A 跳转到 B |
A_onPause() -> B_onCreate() -> B_onStart() -> B_onResume() -> A_onStop() |
从 B 再次回到 A |
B_onPause() -> A_onRestart() -> A_onStart() -> A_onResume() -> B_onStop() |
用户按 home 键 |
onPause() -> onStop() |
按 home 键后回到应用 |
onRestart() -> onStart() -> onResume() |
用户按电源键屏保 |
onPause() -> onStop() |
用户按电源键亮屏 |
onRestart() -> onStart() -> onResume() |
用户按 back 键回退 |
onPause() -> onStop() -> onDestroy() |
表中生命周期的验证能够在 Activity关于生命周期一些问题的实践验证 文章中查看。布局
2.3 关于生命周期常见问题
问题 |
回调 |
由活动 A 启动活动 B时,活动 A 的 onPause() 与 活动 B 的 onResume() 哪个先执行? |
活动 A 的 onPause() 先执行,活动 B 的 onResume() 方法后执行 |
标准 Dialog 是否会对生命周期产生影响 |
没有影响 |
全屏 Dialog 是否会对生命周期产生影响 |
没有影响 |
主题为 Dialog 的 Activity 是否会对生命周期产生影响 |
有影响,与跳转 Activity 同样 |
关于生命周期的常见问题的验证能够在 Activity关于生命周期一些问题的实践验证 文章中查看。post
2.4 异常状态下活动的生命周期
当 Activity 在运行过程当中发生一些状况时,生命周期流程也会发生变化。常见的异常状况有两种,一种是资源配置改变;另外一是内存不足致使生命周期流程发生变化。字体
2.4.1 资源配置改变致使 Activity 重建
资源配置最多见的状况就是横竖屏切换致使资源的变化,当程序启动时,会根据不一样的配置加载不一样的资源,例如横竖屏两个状态对应着两张不一样的资源图片。若是在使用过程当中屏幕忽然旋转,那么 Activity 就会由于系统配置发生改变而销毁重建,加载合适的资源。ui
2.4.2 低优先级 Activity 因为内存不足被杀死
后台能够同时运行多个任务,当设备的内存空间不足时,系统为了保证用户的体验,会按照进程优先级将一些低优先级的进程杀死以会回收内存资源,后台 Activity 就有可能会被销毁。spa
系统回收进程的优先级:code
(1) 前台进程
持有用户正在交互的 Activty,即生命周期处于 onResume 状态的活动。
该进程有绑定到正在交互的 Activity 的 service 或前台 service。
(2) 可见进程
这种进程虽然不在前台,可是仍然可见。
该进程持有的 Activity 执行了 onPause 但未执行 onStop 。例如原活动启动了一个 dialog 主题的 Activity,但此时原活动并不是彻底不可见。
该进程有 service 绑定到可见的或前台 Activity。
(3)服务进程
进程中持有一个 service,同时不属于上面两种状况。
(4)后台进程
不属于上面三种状况,但进程持有一个不可见的 Activity,即执行了 onStop 但未执行 onDestory 的状态。
(5)空进程
不包含任何活跃的应用组件,做用是加快下次启动这个进程中组件所须要的时间,优先级低。
2.5 异常状况下的处理
在发生异常状况后,用户再次回到 Activity,原 Activity 会从新创建,原已有的数据就会丢失,好比用户操做改变了一些属性值,重建以后用户就看不到以前操做的结果,在异常的状况下如何给用户带来好的体验,有两种办法。
2.5.1 数据保存
第一种就是系统提供的 onSaveInstanceState 和 onRestoreInstanceState 方法,onSaveInstanceState 方法会在 Activity 异常销毁以前调用,用来保存须要保存的数据,onRestoreInstanceState 方法在 Activity 重建以后获取保存的数据。
在活动异常销毁以前,系统会调用 onSaveInstanceState,能够在 Bundle 类型的参数中保存想要的信息,以后这个 Bundle 对象会做为参数传递给 onRestoreInstanceState 和 onCreate 方法,这样在从新建立时就能够获取数据了。
关于 onSaveInstanceState 与 onRestoreInstanceState 方法须要注意的一些问题:
1. onSaveInstanceState 方法的调用时机是在 onStop 以前,与 onPause 没有固定的时序关系。而 onRestoreInstanceState 方法则是在 onStart 以后调用。
2. 正常状况下的活动销毁并不会调用这两个方法,只有当活动异常销毁而且有机会重现展现的时候才会进行调用,除了资源配置的改变外,activity 因内存不足被销毁也是经过这两个方法保存数据。
3. 在 onRestoreInstanceState 和 onCreate 均可以进行数据恢复工做,可是根据官方文档建议采用在 onRestoreInstanceState 中去恢复。
4. 在 onSaveInstanceState 和 onRestoreInstanceState 这两个方法中,系统会默认为咱们进行必定的恢复工做,具体地讲,默认实现会为布局中的每一个 View 调用相应的 onSaveInstanceState() 方法,让每一个视图都能提供有关自身的应保存信息。Android 框架中几乎每一个小部件都会根据须要实现此方法,以便在重建 Activity 时自动保存和恢复付 UI 所作的任何可见更改。例如 EditText 中的文本信息、ListView 中的滚动位置等。也能够经过 android:saveEnabled 属性设置为 “false” 或经过调用 setSaveEnabled() 方法显式阻止布局内的视图保存其状态,一般不会将该属性停用,除非想要以不一样方式恢复 Activity IU 的状态。
5. onSveInstanceState() 常见的触发场景有:横竖屏切换、按下电源键、按下菜单键、切换到别的 Activity 等;onRestoreInstanceState() 常见的触发场景有:横竖屏切换、切换语言等等。
2.5.2 防止重建
在默认状况下,资源配置改变会致使活动的从新建立,可是能够经过对活动的 android:configChanges 属性的设置使活动防止从新被建立。
android:configChanges 属性值
属性值 |
含义 |
mcc |
SIM 卡惟一标识IMSI(国际移动用户标识码)中的国家代码,由三位数字组成,中国为:460,这里标识 mcc 代码发生了变化 |
mnc |
SIM 卡惟一标识 IMSI(国际移动用户标识码)中的运营商代码,有两位数字组成,中国移动 TD 系统为 00 ,中国联通为 01,电信为 03,此项标识 mnc 发生了改变 |
locale |
设备的本地位置发生了改变,通常指的是切换了系统语言 |
touchscreen |
触摸屏发生了改变 |
keyboard |
键盘类型发生了改变,好比用户使用了外接键盘 |
keyboardHidden |
键盘的可访问性发生了改变,好比用户调出了键盘 |
navigation |
系统导航方式发生了改变 |
screenLayout |
屏幕布局发生了改变,极可能是用户激活了另一个显示设备 |
fontScale |
系统字体缩放比例发生了改变,好比用户选择了个新的字号 |
uiMode |
用户界面模式发生了改变,好比开启夜间模式 -API8 新添加 |
orientation |
屏幕方向发生改变,好比旋转了手机屏幕 |
screenSize |
当屏幕尺寸信息发生改变(当编译选项中的 minSdkVersion 和 targeSdkVersion 均低于 13 时不会致使 Activity 重启 ) API 13 新添加 |
smallestScreenSize |
设备的物理尺寸发生改变,这个和屏幕方向不要紧,好比切换到外部显示设备 -API13 新添加 |
layoutDirection |
当布局方向发生改变的时候,正常状况下没法修改布局的 layoutDirection 的属性 -API17 新添加 |
能够在属性中声明多个配置值,方法使用 “|” 字符分割这些配置值。
API 级别 13 或更高版本的应用时,若要避免因为设备方向改变(横竖屏切换)而致使运行时重启,则除了 “orientation” 值以外,还必须添加 “screenSize” 值。
当其中一个配置发生变化时,Activity 不会重启。相反,Activity 会收到对 onConfigurationChanged() 的调用。向此方法传递 Configuration 对象指定新设备配置。能够经过读取 Configuration 中的字段,肯定新配置,而后经过更新界面中使用的资源进行适当的更改。
异常状态下生命周期与异常状况下的处理的的验证能够在 Activity关于生命周期一些问题的实践验证 文章中查看。
3 关于 Activity 的不经常使用的回调方法
3.1 onPostCreate()
onPostCreate() 方法是指 onCreate() 方法完全执行完毕的回调。通常咱们都没有实现这个方法,它的做用是在代码开始运行以前,调用系统作最后的初始化工做。如今知道的作法是使用 ActionBarDrawerToggle 时在屏幕旋转的时候在 onPostCreate() 中同步下状态。
3.2 onPostResume()
onPostResume() 与 onPostCreate() 方法相似,onPostResume() 方法在 onResume() 方法完全执行完毕的回调。 onCreate() 方法中获取某个 View 的高度和宽度时,返回的值是 0 ,由于这个时候 View 可能还没初始化好,可是在 onPostResume() 中获取就不会有问题,由于 onPostResume() 是在 onResume() 完全执行完毕的回调。
3.3 onContentChanged()
当 Activity 的布局改动时,即 setContentView() 或者 addContentView() 方法执行完毕时就会调用该方法。因此,Activity 中 View 的 findViewById() 方法均可以放到该方法中。
3.4 onUserInteraction()
Activity 不管分发按键事件、触摸事件或者轨迹球事件都会调用 Activity#onUserInteraction()。若是想知道用户用某种方式和你正在运行的 activity 交互,能够重写 Activity#onUserInteraction()。全部调用 Activity#onUserLeaveHint() 的回调都会首先回调 Activity#onUserInteraction() 。
Activity 在分发各类事件的时候会调用该方法,注意:启动另外一个 activity ,Activity#onUserInteraction()会被调用两次,一次是 activity 捕获到事件,另外一次是调用 Activity#onUserLeaveHint() 以前会调用 Activity#onUserInteraction() 。
能够用这个方法来监控用户有没有与当前的 Activity 进行交互。
3.5 onUserLeaveHint()
当用户的操做使一个 activity 准备进入后台时,此方法会像 activity 的生命周期的一部分被调用。例如,当用户按下 Home 键,Activity#onUserLeaveHint() 将会被调用。可是当来电致使 activity 自动占据前台(系统自动切换),Activity#onUserLeaveHint() 将不会被回调。
通常监听返回键,是重写 onKeyDown() 方法,可是 Home 键和 Menu 键就很差监听,可是能够在 onUserLeaveHint() 方法中监听。
参考文章:
- 老生常谈-Activity
- 全面了解 Activity
- 超详细的生命周期图-你能回答全吗
- Android之Activity系列总结(一)—Activity概览