Android Activity生命周期与启动模式
Activity的完整生命周期如下图:
Activity的加载模式有四种:
standard: 标准模式,默认的加载模式,每次通过这种模式启动目标Acitivity,都创建一个新的实例,并将该Activity添加到当前栈中。
singleTop: 与标准模式类似,只有当Activity位于Task顶时,系统不会重新创建目标Activity的示例,而是直接复用已有的Activity实例。
singleTask:
如果要启动的Activity不存在,系统创建Activity实例,并将它加入栈顶
如果将启动的Activity存在,已经位于栈顶,此时与singleTop行为相同
如果要启动的Activity存在,但不是位于栈顶,系统会使Activity上面所有的Activity出栈。
singleInstance:
如果要启动的Activity不存在,系统会创建一个新的Task,再创建Activity实例,将它加入新Task的栈顶
如果要启动的Activity存在,无论它在哪个应用程序中,系统都会把该Activity所在的Task转至前台。
下面依次验证,再四种加载模式下,Activity的各生命周期如何执行。假设有Activity A,B,C
1、标准模式启动A->B->C
//启动A D/activityA(19864): onCreate D/activityA(19864): onStart D/activityA(19864): onResume //启动B D/activityA(19864): onPause D/activityB(19864): onCreate D/activityB(19864): onStart D/activityB(19864): onResume D/activityA(19864): onStop //启动C D/activityB(19864): onPause D/activityC(19864): onCreate D/activityC(19864): onStart D/activityC(19864): onResume D/activityB(19864): onStop
然后按返回建:
D/activityC(19864): onPause D/activityB(19864): onRestart D/activityB(19864): onStart D/activityB(19864): onResume D/activityC(19864): onStop D/activityC(19864): onDestory
所以如果未调用onDestory重新启动的话,不会调用onCreate,而是会调用onRestart。
2、A->B->A
D/activityA(19864): onCreate D/activityA(19864): onStart D/activityA(19864): onResume D/activityA(19864): onPause D/activityB(19864): onCreate D/activityB(19864): onStart D/activityB(19864): onResume D/activityA(19864): onStop D/activityB(19864): onPause D/activityA(19864): onCreate D/activityA(19864): onStart D/activityA(19864): onResume D/activityB(19864): onStop
修改A的启动模式为singleTop
->A->A
D/activityA(27075): onCreate D/activityA(27075): onStart D/activityA(27075): onResume D/activityA(27075): onPause D/activityA(27075): onNewIntent D/activityA(27075): onResume
->A->B->A
D/activityA(27075): onCreate D/activityA(27075): onStart D/activityA(27075): onResume D/activityA(27075): onPause D/activityB(27075): onCreate D/activityB(27075): onStart D/activityB(27075): onResume D/activityA(27075): onStop D/activityB(27075): onPause D/activityA(27075): onCreate D/activityA(27075): onStart D/activityA(27075): onResume D/activityB(27075): onStop
当A不是栈顶时,启动A,又重新创建了A,而且观察以上输出,两个Activity切换时,首先当前Activity先onPause,然后被启动的Activity,依次onCreate, onStart, onResume显示出来之后,之前的Activity才会onStop。
修改A的启动方式为singleTask,
->A->A
D/activityA( 2744): onCreate D/activityA( 2744): onStart D/activityA( 2744): onResume D/activityA( 2744): onPause D/activityA( 2744): onNewIntent D/activityA( 2744): onResume
当A不存在时,创建A,当A存在且在栈顶时,先onPause,然后onNewIntent,之后onResume。
->A->B->A
D/activityA( 2744): onCreate D/activityA( 2744): onStart D/activityA( 2744): onResume D/activityA( 2744): onPause D/activityB( 2744): onCreate D/activityB( 2744): onStart D/activityB( 2744): onResume D/activityA( 2744): onStop D/activityB( 2744): onPause D/activityA( 2744): onNewIntent D/activityA( 2744): onRestart D/activityA( 2744): onStart D/activityA( 2744): onResume D/activityB( 2744): onStop D/activityB( 2744): onDestory
可以看到第二次启动A后,A调用了onNewIntent,onRestart,onStart,onResume,关键是之后调了B的onStop, onDestory,在之前的两种模式下只是另B,调用了onStop,所以推断,singleTask时,是之前的A通过onNewIntent重新进入onResume,然后将B移除出了栈。
修改A的启动方式为SingleInstance
->A->A
D/activityA(10578): onCreate D/activityA(10578): onStart D/activityA(10578): onResume D/activityA(10578): onPause D/activityA(10578): onNewIntent D/activityA(10578): onResume
与singleTask表现一致
->A->B->A
D/activityA(10578): onCreate D/activityA(10578): onStart D/activityA(10578): onResume D/activityA(10578): onPause D/activityB(10578): onCreate D/activityB(10578): onStart D/activityB(10578): onResume D/activityA(10578): onStop D/activityB(10578): onPause D/activityA(10578): onNewIntent D/activityA(10578): onRestart D/activityA(10578): onStart D/activityA(10578): onResume D/activityB(10578): onStop
在singleInstance模式下,复用了原来的A,对B只是onStop,并没有发生出栈销毁。
总结以上:
当复用一个已经存在的Activity时,通常是从它的onNewIntent或onRestart开始调起,
如果一个Activity要出栈,必然会调到onDestory
在两个Activity切换的过程中,是当前的Activity先onPause,然后让新的Activity创建或者restart,知道onResume,前一个Activity才会走onStop以及onDestory
另外一个问题:分别在A生命周期函数内启动B(A,B都是Standared),
D/activityA(17860): onCreate D/activityA(17860): onStart D/activityA(17860): onResume D/activityA(17860): onPause D/activityB(17860): onCreate D/activityB(17860): onStart D/activityB(17860): onResume D/activityA(17860): onStop
生命周期的回调函数是完整的,都会依次调到,但是有个问题是当按back键后,会出现如下:
D/activityB(19588): onPause D/activityA(19588): onRestart D/activityA(19588): onStart D/activityA(19588): onResume D/activityA(19588): onPause D/activityB(19588): onCreate D/activityB(19588): onStart D/activityB(19588): onResume D/activityB(19588): onStop D/activityB(19588): onDestory D/activityA(19588): onStop
需要返回A,但是A在启动的生命周期中又启动了B,这时的行为就跟启动模式有关了,总是它正常切换时正确的执行顺序。
这个知识点太绕了,其实万变不离其宗,都是四种启动模式生命周期执行顺序的组合。