Android开发笔记(三十九)Activity的生命周期

与生命周期有关的方法

下面是Activity类与生命周期有关的方法:
onCreate : 创建页面
onStart : 开始页面
onStop : 停止页面
onResume : 恢复页面
onPause : 暂停页面
onDestroy : 销毁页面
onRestart : 重启页面
onNewIntent : 重用栈中已存在的实例
onSaveInstanceState : 保存实例状态。使用场景:1、从A视图跳转到B视图,需要保存A视图的状态(不考虑特殊情况);2、屏幕从竖屏变为横屏,需要保存竖屏时的视图状态,从横屏变为竖屏亦然;3、当前Activity处于后台,系统因资源紧张将其杀死。
onRestoreInstanceState : 恢复实例状态。使用场景:1、屏幕从竖屏变为横屏,横屏显示时需要恢复之前保存的竖屏状态;2、activity后台运行被系统杀死。此处注意,从B视图返回A视图时并不调用该方法。
最简单的页面启动顺序:onCreate->onStart->onResume
最简单的页面退出顺序:onPause->onStop->onDestroy



默认设置时的生命周期

普通场景

打开主页面(原进程已经结束),方法调用顺序为:主页面onCreate->onStart->onResume。日志如下:
01-04 12:45:05.838: D/MainActivity(2909): onCreate
01-04 12:45:05.838: D/MainActivity(2909): onStart
01-04 12:45:05.838: D/MainActivity(2909): onResume


从上级视图跳转到下级视图,方法调用顺序为:上级视图onPause->下级视图onCreate->onStart->onResume->上级视图onSaveInstanceState->onStop。日志如下:
01-04 13:56:05.905: D/MainActivity(1638): onPause
01-04 13:56:05.925: D/FirstActivity(1638): onCreate
01-04 13:56:05.925: D/FirstActivity(1638): onStart
01-04 13:56:05.925: D/FirstActivity(1638): onResume
01-04 13:56:06.389: D/MainActivity(1638): onSaveInstanceState mState=0
01-04 13:56:06.389: D/MainActivity(1638): onStop


从下级视图回到上级视图(按返回键或代码中调用finish方法),方法调用顺序为:下级视图onPause->上级视图onRestart->onStart->onResume->下级视图onStop->onDestroy。日志如下:
01-04 14:03:06.461: D/SecondActivity(1983): onPause
01-04 14:03:06.465: D/MainActivity(1983): onRestart
01-04 14:03:06.465: D/MainActivity(1983): onStart
01-04 14:03:06.465: D/MainActivity(1983): onResume
01-04 14:03:07.069: D/SecondActivity(1983): onStop
01-04 14:03:07.069: D/SecondActivity(1983): onDestroy


在主页面按返回键,方法调用顺序为:主页面onPause->onStop->onDestroy。日志如下:
01-04 13:51:51.977: D/MainActivity(1638): onPause
01-04 13:51:52.657: D/MainActivity(1638): onStop
01-04 13:51:52.657: D/MainActivity(1638): onDestroy


特殊场景

长按主页键弹出进程列表,方法调用顺序为:主页面onPause->onSaveInstanceState->onStop。日志如下:
01-04 13:52:43.881: D/MainActivity(1638): onPause
01-04 13:52:44.353: D/MainActivity(1638): onSaveInstanceState mState=0
01-04 13:52:44.353: D/MainActivity(1638): onStop


在进程列表中返回视图A(原进程尚未结束),方法调用顺序为:主页面onRestart->onStart->onResume。日志如下:
01-04 13:53:12.905: D/MainActivity(1638): onRestart
01-04 13:53:12.905: D/MainActivity(1638): onStart
01-04 13:53:12.905: D/MainActivity(1638): onResume


竖屏转横屏,方法调用顺序为:竖屏页面onPause->onSaveInstanceState->onStop->onDestroy->横屏页面onCreate->onStart->onRestoreInstanceState->onResume。日志如下:
01-04 14:25:42.198: D/MainActivity(26762): onPause
01-04 14:25:42.199: D/MainActivity(26762): onSaveInstanceState mState=0
01-04 14:25:42.199: D/MainActivity(26762): onStop
01-04 14:25:42.199: D/MainActivity(26762): onDestroy
01-04 14:25:42.330: D/MainActivity(26762): onCreate
01-04 14:25:42.330: D/MainActivity(26762): onStart
01-04 14:25:42.330: D/MainActivity(26762): onRestoreInstanceState mState=1
01-04 14:25:42.330: D/MainActivity(26762): onResume



设置启动模式时的生命周期

启动模式的概念

launchMode是Android中用来控制Activity栈行为的启动模式。APP在运行期间,打开的页面会被逐个加入一个页面栈。一般来说位于栈顶的是APP首页,其后打开的页面依次加到栈尾,返回时从栈尾依次出栈。但出于效率考虑,我们有时希望对栈的操作能够不按顺序处理,所以也就有了启动模式launchMode。launchMode可作为activity的属性加入到AndroidManifest.xml,取值说明如下:
standard : 标准模式,无论何时启动哪个activity,都是重新创建该页面的实例并放入栈尾。该值为launchMode的默认值,上面“默认设置时的生命周期”就是standard的情况。
singleTop : 启动activity时,判断如果栈顶正好就是该Activity的实例,则重用该实例;否则创建新的实例并放入栈顶,否则的情况与standard类似。
singleTask : 启动activity时,判断如果栈中存在该Activity的实例,则重用该实例,并清除位于该实例上面的所有实例;否则的情况处理同standard。
singleInstance : 启动activity时,将该Activity的实例放入一个新栈中,原栈的实例列表保持不变。
下面是具体场景下各启动模式的处理流程:


主页面跳转到下级页面,再从下级页面跳转到主页面

(是跳转,不是按返回键)
launchMode="standard"时,处理流程与默认设置时保持一致。日志如下:
01-04 14:31:48.765: D/FirstActivity(3034): onPause
01-04 14:31:48.789: D/MainActivity(3034): onCreate
01-04 14:31:48.793: D/MainActivity(3034): onStart
01-04 14:31:48.793: D/MainActivity(3034): onResume
01-04 14:31:49.237: D/FirstActivity(3034): onSaveInstanceState mState=0
01-04 14:31:49.237: D/FirstActivity(3034): onStop


launchMode="singleTop"
从下级视图跳转到上级视图,因为此时位于栈顶的是下级视图,不是上级视图,所以此时处理流程与默认设置时保持一致,即与launchMode="standard"情况相同。


launchMode="singleTask"
因为此时栈中存在上级视图的实例,所以系统重用该实例,并将该实例上部的所有实例出栈(下级视图调用了onDestroy方法)。日志如下:
01-04 14:29:20.989: D/FirstActivity(2922): onPause
01-04 14:29:21.001: D/MainActivity(2922): onNewIntent
01-04 14:29:21.001: D/MainActivity(2922): onRestart
01-04 14:29:21.001: D/MainActivity(2922): onStart
01-04 14:29:21.001: D/MainActivity(2922): onResume
01-04 14:29:21.453: D/FirstActivity(2922): onStop
01-04 14:29:21.453: D/FirstActivity(2922): onDestroy


launchMode="singleInstance"
上级视图被重用的同时加入到一个新栈,原栈中实例列表保持不变,所以下级实例无需出栈。日志如下:
01-04 14:34:56.721: D/FirstActivity(3286): onPause
01-04 14:34:56.733: D/MainActivity(3286): onNewIntent
01-04 14:34:56.733: D/MainActivity(3286): onRestart
01-04 14:34:56.733: D/MainActivity(3286): onStart
01-04 14:34:56.733: D/MainActivity(3286): onResume
01-04 14:34:57.569: D/FirstActivity(3286): onSaveInstanceState mState=0
01-04 14:34:57.569: D/FirstActivity(3286): onStop


从自身跳到自身

launchMode="standard"
standard模式不管什么时候,都是重新创建该Activity的实例。日志如下:
01-04 14:43:24.661: D/MainActivity(3740): onPause
01-04 14:43:24.673: D/MainActivity(3740): onCreate
01-04 14:43:24.673: D/MainActivity(3740): onStart
01-04 14:43:24.677: D/MainActivity(3740): onResume
01-04 14:43:25.101: D/MainActivity(3740): onSaveInstanceState mState=0
01-04 14:43:25.105: D/MainActivity(3740): onStop


launchMode="singleTop"
因为自身跳到自身,自身视图的实例位于栈顶,所以此时重用栈顶的实例。日志如下:
01-04 14:39:27.309: D/MainActivity(3450): onPause
01-04 14:39:27.309: D/MainActivity(3450): onNewIntent
01-04 14:39:27.309: D/MainActivity(3450): onResume


launchMode="singleTask"
实例位于栈顶还是栈尾,都是位于栈中,所以继续重用该Activity的实例。该情况与launchMode="singleTop"情况相同


launchMode="singleInstance"
同上,该情况与launchMode="singleTop"情况相同


几种启动模式的区别

根据上面具体场景中各启动模式的处理日志,总结这些启动模式的异同点如下:
1、standard与singleTask的区别:只有待跳转的activity已有实例位于栈顶时,singleTask模式才需做特殊处理,其余情况二者是一样的;
2、singleTask与singleTop的区别:只有待跳转的activity已有实例位于栈顶时,二者的处理方式才一样,其余情况都不一样;
3、singleTask与singleInstance的区别:待跳转的activity已有实例位于栈中时,singleTask会把该实例上面的所有实例予以清除,而singleInstance不处理它上面的实例。



设置启动标志时的生命周期

启动标志的概念

上面说的launchMode有个缺点,就是AndroidManifest.xml中对每个Activity只能指定唯一额一种启动模式,如果我们想在不同时候对同一个Activity做不同的处理,显然launchMode无法满足这个要求。所以我们希望可以在代码中手动设置启动模式,在不同时候startActivity能够进行不同的处理,于是就有了Intent的setFlags设置启动标志方法。启动标志的常见取值说明如下:
FLAG_ACTIVITY_NEW_TASK : 开启一个新任务,flags默认该值。该值等同于launchMode="standard"
FLAG_ACTIVITY_SINGLE_TOP : 当栈顶为待跳转的activity实例时,则重用栈顶的实例。该值等同于launchMode="singleTop"
FLAG_ACTIVITY_CLEAR_TOP : 当栈中存在待跳转的activity实例时,则重新创建一个新实例,并将原实例上方的所有实例加以清除。该值与launchMode="singleTask"类似,launchMode="singleTask"采用onNewIntent启用原任务,而FLAG_ACTIVITY_CLEAR_TOP采用先onDestroy再onCreate创建新任务。
下面是具体场景下各启动标志的处理流程:


主页面跳转到下级页面,再从下级页面跳转到主页面

(是跳转,不是按返回键)
FLAG_ACTIVITY_NEW_TASK
与launchMode="standard"情况相同


FLAG_ACTIVITY_SINGLE_TOP
与launchMode="singleTop"情况相同


FLAG_ACTIVITY_CLEAR_TOP
即使栈中已有该Activity的实例,也要清除自身实例后再重新创建。日志如下:
01-04 15:17:32.269: D/FirstActivity(5189): onPause
01-04 15:17:32.269: D/MainActivity(5189): onDestroy
01-04 15:17:32.289: D/MainActivity(5189): onCreate
01-04 15:17:32.289: D/MainActivity(5189): onStart
01-04 15:17:32.289: D/MainActivity(5189): onResume
01-04 15:17:32.757: D/FirstActivity(5189): onStop
01-04 15:17:32.757: D/FirstActivity(5189): onDestroy


自身跳到自身

FLAG_ACTIVITY_NEW_TASK
与launchMode="standard"情况相同


FLAG_ACTIVITY_SINGLE_TOP
与launchMode="singleTop"情况相同


FLAG_ACTIVITY_CLEAR_TOP
自身实例也不放过,同样是启动新实例后暴力清除自身的原实例。日志如下:
01-04 15:11:36.021: D/MainActivity(4766): onPause
01-04 15:11:36.037: D/MainActivity(4766): onCreate
01-04 15:11:36.037: D/MainActivity(4766): onStart
01-04 15:11:36.041: D/MainActivity(4766): onResume
01-04 15:11:36.921: D/MainActivity(4766): onStop
01-04 15:11:36.921: D/MainActivity(4766): onDestroy


其他标志位

另外有两个标志也需注意,即FLAG_ACTIVITY_NO_HISTORY和FLAG_ACTIVITY_CLEAR_TASK,说明如下:


FLAG_ACTIVITY_NO_HISTORY
该标志与launchMode="standard"情况类似,但栈中不保存新启动的activity实例。这样下次无论以何种方式再启动该实例,也要走standard的完整流程。


FLAG_ACTIVITY_CLEAR_TASK
该标志非常暴力,跳转到新页面时,栈中的原有实例都被清空。该标志需要结合FLAG_ACTIVITY_NEW_TASK使用,即setFlags的参数为“Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK”。下面是从上级视图跳转到下级视图的日志:
01-04 15:08:05.681: D/MainActivity(4507): onPause
01-04 15:08:05.713: D/FirstActivity(4507): onCreate
01-04 15:08:05.713: D/FirstActivity(4507): onStart
01-04 15:08:05.713: D/FirstActivity(4507): onResume
01-04 15:08:06.549: D/MainActivity(4507): onStop
01-04 15:08:06.549: D/MainActivity(4507): onDestroy




点此查看Android开发笔记的完整目录

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