先直观地看一下Activity的生命周期的流程图,然后我们一个一个来说明每个方法在什么情况下被回调。
- onCreate():在Activity被创建的时候回调,这是生命周期的第一个方法,我们可以在这个方法里面加载界面布局资源,初始化Activity需要的数据。
- onRestart():在Activity从不可见变为可见时被调用。
- onStart():在Activity正在被启动的时候调用(这个时候Activity已经被绘制出来了,但是还没有展现在前台)。
- onResume():在Activity展示在前台,可以和用户交互的时候被调用。
- onPause():在Activity失去焦点的时候被调用。
- onStop():在Activity不可见时被调用(一般在onStop前都会调用onPause)
- onDestory():在Activity要被销毁的时候调用,可以做一些回收和资源释放的工作。
我们应该明确每个方法在什么情况下会被调用,而方法被调用的时候出于何种状态,只是侧重点。
从整个生命周期来说,onCreate和onDestory是配对的,分别对应这Activity的创建和销毁;从Activity是否可见来说,onStart和onPause是配对的;从Activity是否在前台来说,onResume和onStop是配对的。
异常情况下的Activity生命周期,有以下两种情况:
- 资源相关的系统配置发生改变,导致Activity被销毁重建。
这种情况很容易发生,比如说我们由竖屏幕状态改变为横屏状态,系统的配置发生了改变,默认情况就会销毁Activity然后重新创建Activity,在这种情况下Activity的销毁会回调一个onSaveInstanceState()的回调,用于保存一些数据和状态,并且在创建时会调用onRestoreInstanceState()恢复这些数据和状态。 系统内存不足导致低优先级的Activity被杀死。
Activity有一定优先级的,处于前台与用户交互的Activity的优先级最高,可见但不在前台的Activity优先级次之,最后是已经被暂停的Activity,优先级最低,当系统内存不足的时候,低优先级的Activity可能会被销毁掉。这种情况下Activity的数据存储与恢复与1的情况一样。对于情况1,系统配置发生改变的时候,默认Activity会重建,我们可以通过在Activity里面设置configChanges属性为”orientation | screenSize”(对于minSdkVersion或者targetSdkVersion大于13的,需要设置screenSize属性)然后当屏幕发生旋转的时候,就不会重建Activity,而是调用onConfigChanges()方法。提供一下不希望重建的应用场景:当我们在竖屏状态下播放音乐的时候,改为横屏状态,我们并不希望音乐从头播放。
local:设备的本地位置发生了变化,一般指切换了语言。
keybordHidden:键盘的可访问性发生了变化,比如,用户调出来键盘。
orientation:屏幕的方向发生了改变。
screenSize:屏幕的尺寸信息发生了改变,当旋转设备的时候,就会变化。(当minSdkVersion和targetSdkVersion都小于13的时候,该选项不会导致Activity重启)
Activity的启动模式:standard、singleTop、singleTask、singleInstance
standard:标准模式,也是系统默认的模式,每次启动Activity都会创建新的实例,这种模式下,谁启动了该Activity,那么这个Activity就运行在启动它的Activity所在的任务栈中。
singleTop:栈顶复用模式,当启动的Activity实例已经存在,并且位于任务栈的栈顶的时候,不会再重新创建Activity,而是复用栈顶的Activity,同时也不会走onStart和onResume生命周期,只会回调onNewIntent()方法。
singleTask:栈内复用模式,只要启动的Activity位于任务栈中,就复用该Activity,不过这里有两点需要注意,比如我们要启动的Activity为A
- 系统会先去找是否存在A需要的任务栈,a. 如果不存在,就创建栈,然后创建A的实例压入栈中;如果存在,再判断栈中是否存在A的实例, b. 如果不存在A的实例,那么就创建A的实例压入栈中,c. 如果存在A的实例,那么就将A弹到栈顶。
- 对于情况c. 在A弹出实例A的时候,A之前的Activity会被销毁。