前言
Activity 生命周期是研究 Android 开发最基础的知识点之一, 熟练掌握生命周期的特性可以在实际开发中避免踩坑. 比如, 一些 UI 的初始化和回收操作, 框架库的注册于反注册(摧毁), 线程的启动和停止等. 另外, 本文在最后章节还会讲解系统回收造成的问题. 本文就是针对各生命周期进行分析和解答, 帮助大家完全掌握生命周期.
一, 基本作用
Activity 的生命周期共七个指示器: onCreate,onStart,onResume,onPause,onStop,onDestroy,onRestart.
如下图所示.
(1)onCreate() , 不可见状态
在 Activity 被创建时回调, 第一个生命周期. 我们一般在创建 Activity 时需要重写该方法做一些初始化的操作, 如通过 setContentView 设置界面布局的资源, 初始化所需要的组件信息等.
(2)onStart() , 可见状态
该方法回调表示 Activity 正在启动, 此时 Activity 处于可见状态, 只是还没有在前台显示, 因此用户也无法交互. 可以简单理解为 Activity 已显示却无法被用户看见.
(3)onResume() , 可见状态
此方法回调时, Activity 已在在屏幕上显示 UI 并允许用户操作了. 从流程图可见, 当 Activity 停止后(onPause,onStop 方法被调用), 重新回到前台时也会调用 onResume 方法. 可以在 onResume 方法中初始化一些资源, 比如打开相机或开启动画.
(4)onPause() , 可见状态
此方法回调时, Activity 正在停止(Paused 形态), 通常接下来 onStop() 会被回调 . 但通过流程图可见, 另一种情况是 onPause() 执行后直接执行了 onResume 方法, 这可能是用户点击 Home 键, 让程序退回到主界面, 程序在后台运行时又迅速地再回到到当前的 Activity, 此时 onResume 方法就会被回调. 我们可以在 onPause 方法中做一些数据存储, 动画停止, 资源回收等操作. 另外, onPause 方法执行完成后, 新 Activity 的 onResume 方法才会被执行. 所以 onPause 不能太耗时, 因为这可能会影响到新的 Activity 的显示.
(5)onStop() , 不可见状态
此方法回调时, Activity 即将停止或者完全被覆盖(Stopped 形态), 此时 Activity 不可见, 仅在后台运行. 同样地, 在 onStop 方法可以做一些资源释放的操作, 不能太耗时.
(6) onRestart(), 可见状态
此方法回调时, 表示 Activity 正在重新启动, 由不可见状态变为可见状态. 这种情况, 一般发生在用户打开了一个新的 Activity 时, 之前的 Activity 就会被 onStop, 接着又回到之前 Activity 页面时, 之前的 Activity 的 onRestart 方法就会被回调.
(7)onDestroy() , 不可见状态
此方法回调时, 表示 Activity 正在被销毁, 也是生命周期最后一个执行的方法, 一般我们可以在此方法中做一些回收工作和最终的资源释放.
三, 问题思考(难度升级)
1, 如果所有的初始化都在 onCreate()中实现, 会有什么问题?
首先, Activity 的 onCreate()被调用时, Activity 还不可见, 如果要做一些动画, 既然视图还不存在, 在 onCreate 中来启动动画, 明显有问题;
其次, AActivity 切换到 BActivity, 再切换到 AActivity, 由于实例已经存在, 所以 onCreate 不会再被调用, 那问题就在于 AActivity 从后台切换至前台时, 有可能需要一些初始化, 就没法被调用到了.
2, 如果所有的初始化都在 onStart()中实现, 会有什么问题?
首先, 虽然 在 onStart()中用 setContentView(),findViewById() 功能也是正常的, 但是 onCreate()注释中, 明确建议 setContentView(),findViewById() 要在 onCreate() 中被调用.
其次, onResume()的注释中都明确地说了这不是 Activity 对用户是可见的最好的指示器, 如果在 onStart() 中做全部初始化, 很有可能初始化还没完成影响到用户的交互体验.
3, 如果所有资源回收都在 onStop()中实现, 会有什么问题?
首先, 在 onResume() 的注释中, 建议是在 onResume()中打开独占设备 (比如相机), 与 onResume() 对应的是 onPause(), 关闭相机的操作也应该在此方法中被调用; 否则, 考虑一下如下场景: 如果 AActivity 打开了相机, 我们点击某按钮要跳转到 BActivity 中, BActivity 也想打开相机; 假设 AActivity 的 onPause() 在 BActivity 启动后再被调用, 那 BActivity 根本就无法再正常启动相机.
在 onPause() 的注释中明确表示, 应该在这个方法中执行停止动画等比较耗 CPU 的操作, 如果不先执行这些操作, 就先启动新应用, 然后再来执行此操作, 确实是不合逻辑; 其次, onStop() 的注释中也明确地写了, 在内存不足而导致系统自动回收进程情况下, onStop() 可能都不会被执行.
4,Activity 间跳转时, 为什么 AActivity 的 onPause()被调用后, BActivity 的初始化流程 (onCreate() -> onStart() -> onResume()), 然后 AActivity 的 onStop() 被调用?
从 AActivity 切换到 BActivity 的日志如下:
- 10-17 20:54:46.997: I/com.example.servicetest.AActivity(5817): onPause()
- 10-17 20:54:47.021: I/com.example.servicetest.BActivity(5817): onCreate()
- 10-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onStart()
- 10-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onResume()
- 10-17 20:54:47.099: I/com.example.servicetest.AActivity(5817): onStop()
当用户点击打开新的 Activity, 肯定是想尽快进入新的视图进行操作. 而且上面的问题已经解释了, 在 onResume()一般会打开独占设备, 开启动画等, 当需要从 AActivity 切换到 BActivity 时, 先执行 AActivity 中的 onPause()进行关闭独占设备, 关闭动画等, 以防止 BActivity 也需要使用这些资源, 因为 AActivity 的资源回收, 也有利于 BActivity 运行的流畅.
当 AActivity 中比较消耗资源的部分在 onPause()中关闭后, 再执行 BActivity 的初始化, 显示视图与用户交互. 然后, 系统在后台默默执行 AActivity 的 onStop()操作, 去回收 AActivity 占用的其余资源. 即使 onStop()中会有些比较耗时的操作, 也没有关系, 这是在后台执行也不会影响到用户的体验.(设计的非常好! good!!!)
四, onSavedInstanceState()和 onRestoreInstanceState()理解
大家在开发过程中可能遇到, 当在页面的 EditText 中输入值, 接着翻转屏幕时, 我输入的内容清空了, 但是当我给 EditText 定义了 id 属性, 再执行上诉操作时, EditText 的内容仍然存在. 另外, 当我们点击 Home 键退回到主页面, 许久之后再次打开程序进行操作, 可能会崩溃.
下面解释为什么会出现这样的情况:
(1)onSavedInstanceState()和 onRestoreInstanceState()并不是 activity 生命周期的方法.
onSaveInstanceState()会在 onPause()或 onStop()之前执行;
onRestoreInstanceState()会在 onStart()和 onResume()之间执行.
当应用遇到意外情况 (内存不足, 用户直接按 home 键) 由系统直接销毁一个 Activity 时, onSaveInstanceState()就会调用, 但是当用户主动销毁 activity, 如按 back 键, 或直接执行 finish(), 这种情况下 onSaveInstanceState()就不会执行, 因为这种情况下, 用户的行为决定了不需要保存 Activity 的状态.
(2)那么 onRestoreInstanceState()会跟 onSaveInstanceState()成对出现吗?
答案是不会成对出现, onSaveInstanceState()需要调用的时, activity 可能销毁, 也可能没有销毁, 只有在 activity 销毁重建的时候 onRestoreInstanceState()才会调用.
(3)在 onSaveInstanceState()中默认情况下具体干些什么?
默认情况下默认会自动保存 Activity 中的某些状态, 比如 activity 中各种 UI 的状态, 因此在 activity 被 "系统" 销毁和重建的时候, 这些 Ui 的状态会默认保存, 但是前提条件是 Ui 控件必须制定 id, 如果没有指定 id 的话, UI 的状态是无法保存 的.
(4)总结下 Activity 数据的保存和恢复:
activity 中保存数据有两种方式 onPause(),onSaveInstance(bundle), 恢复数据也有两种途径 onCreate(Bundle), onRestoreInstanceState(budle), 默认情况下 onSaveInstanceSate()和 onRestoreInstanceState()会对 UI 状态进行保存和恢复, 如果需要保存其他数据可以在 onSaveInstanceState(),onPause()保存. 但是如果是持久化的数据, google 推荐的是通过 onPause()保存.
文末
好了, 文章到这里就结束了如果你觉得文章还算有用的话, 不妨把它们推荐给你的朋友.
最后这里是关于我自己的 Android 学习, 面试文档, 视频收集大整理, 有兴趣的伙伴们可以看看~
来源: http://www.jianshu.com/p/2114ef4e0bc9