前言
Activity生命周期讲解
正文
一. 概述
本文将分析和总结各种情况下, Activity的生命周期情况, 包括正常情况下, 异常情况下(如: 用户屏幕旋转, 资源分配不足等)以及特殊情况下(如: 当Activity上覆盖对话框或者透明Activity, 当按下Home键回到桌面时, 当屏幕熄灭时)Activity生命周期的调用情况; 同时还将简述各个方法下适于做什么工作等
二. 正常情况
2.1 单独的Activity分析
如下为一张典型的Activity生命周期图(摘自官方文档); 也是正常情况下, 一个Activity的经历

记忆的时候可以通过两两配对来记
下面将结合上图讲解各个状态:
-
onCreate(): 一个Activity启动时只调用一次, 表示Activity创建; 可以进行一些数据绑定, 类变量初始化或者上一次UI恢复等工作(通过savedInstanceState实现) -
onStart(): 可见, 处于后台, 不能交互 -
onResume(): 可见, 处于前台 -
onPause(): 时间短暂, 处于后台; 如果在onPause的时候再快速的回到当前Activity, 那么onResume会被调用(一般用户操作很难实现这一场景); 在Android7.0或者更高, 应用可以在多窗口模式下运行, 但是只要每个时刻只有一个应用可以得到焦点, 那么此时就需要暂停另一个应用(处于onPause()状态); (一个处于onPause状态的Activity可能仍然是完全可见的, 比如说在多窗口模式下); 不应该在onPause()执行数据保存工作, 因为该阶段非常短暂, 同时只有onPause()执行完, 新Activity的onResume()才会执行 -
onStop(): 不可见, 可以执行一些稍微重量级的工作, 比如资源释放与数据保存 -
onDestroy(): 表示Activity销毁, 可以做一些最终的回收工作和资源释放 -
onRestart(): 表示当当前Activity从不可见重新变为可见状态时调用
2.2 Activity启动新Activity分析
这里以Activity A正常启动Activity B的情况分析
当A启动B的时候, 会依次执行A.onPause() –> B.onCreate() –> B.onStart() –> B.onResume() –> A.onStop()
可以看出, 只有当A的onPause()方法执行完成之后, B的一系列方法才会调用; 这也说明了onPause()方法中不能执行耗时操作, 因为新Activity的onResume()是在其之后执行的, 如果onPause()中执行太耗时的操作的话, 会影响新Activity的显示; 我们应当尽量在onStop()中操作, 使新Activity尽快显示出来并出现在前台
三. 异常情况
3.1 资源相关系统配置改变导致Activity被杀死并重新创建
默认情况下, 如果不做特殊处理, 当系统配置发生改变之后, Activity就会被杀死并重建; 比如: 当手机进行横竖屏切换的时候, Activity默认就会被销毁重建
在这种情况下, Activity会依次调用onPause –> onSaveInstanceState –> onStop –> onDestroy –> onCreate –> onStart –> onRestoreInstanceState –> onResume
需要注意的是这里和正常情况下不同的是, 需要等到Activity销毁之后才能开始重新创建; 另一个就是, 在Activity销毁的时候, 会调用onSaveInstanceState来保存当前Activity的状态, 该方法的调用在onStop之前, 但是和onPause没有既定的时序关系; 但是onRestoreInstanceState的调用确是在onStart之后, 有既定的时序关系;
当Activity销毁重建保存数据的方法是: 委托下级子元素调用其自己的onSaveInstanceState来保存自己的状态和数据; 即让其关联Window保存数据, Window再委托子View进行数据保存, 最终会调用每个子View的View.onSaveInstanceState()来保存自己的数据
当进行数据恢复的时候, onCreate中的Bundle savedInstanceState参数不为null, 可以在此处进行数据恢复, 但是推荐在onRestoreInstanceState中进行数据恢复
3.2 资源内存不足导致低优先级Activity被杀死
Activity优先级:
- 前台
Activity: 正在和用户交互的Activity, 优先级最高- 可见但非前台
Activity: 比如Activity中弹出了一个对话框, 导致Activity可见但是位于后台, 无法与用户直接交互- 后台
Activity: 已经被暂停的Activity, 比如执行了onStop, 优先级最低
Activity被杀死的可能性如下:

四. 特殊情况
4.1 按下Home键或者当屏幕熄灭
这种情况下会调用onPause –> onSaveInstanceState –> onStop; 需要注意的是这里仍然调用了onSaveInstanceState; 但是该情况下是不会调用onRestoreInstanceState, 原因下面说明
关于onSaveInstanceState和onRestoreInstanceState调用的几点说明:
-
onSaveInstanceState的调用:onSaveInstanceState会在当Activity有可能被销毁的时候调用, 用于进行数据保存; 注意, 只要是Activity有可能被销毁都会调用方法; 比如: 按下Home键或者屏幕熄灭Activity进行后台的时候, 该Activity可能被回收, 所以此时会调用onSaveInstanceState -
onRestoreInstanceState的调用和onSaveInstanceState的调用不一定是成对的,onRestoreInstanceState要调用的前提是当前Activity确实被系统销毁了
4.2 透明对话框或者透明Activity
-
当在
Activity上覆盖一层透明对话框的时候, 不会使Activity进入后台(不会调用任何方法), 但是Activity不可和当前用户交互 -
当当前
Activity启动一个透明Activity的时候, 会调用前一个Activity的onPause, 但是不会调用前一个Activity的onStop, 此时前一个Activity可见但是处于后台
五. 补充
- 考虑
Activity A跳转到B的情况: 如果A跳转到B(使用startActivityForResult()),A被回收的之后再初始化, 此时从B返回, 那么A的onActivityResult()是否还会调用: 参考博客; 结果如下:
在跳转后前一个页面被回收的情况下, 再回到前一个页面,
onActivityResult依然会被调用, 而且是在onCreate和onRestoreInstanceState两个状态恢复结点之后调用, 所以只要做好状态的保存和恢复工作, 就不用担心在onActivityResult回调时 因相关数据丢失而造成的异常了
- 单纯的使用
startActivityForResult()的生命周期经历情况是:- B onPause
- A onActivityResult
- A onRestart
- A onStart
- A onResume
- B onStop
- B onDestroy
A启动B,B返回到A, 经历:- A onPause (—-> A启动B)
- B onCreate
- B onStart
- B onResuem
- A onStop
- B onPause(—–> B返回A)
- A onRestart
- A onStart
- A onResume
- B onStop
- B onDestroy
六. 注
验证代码参见: Github