你的位置:首页 > 操作系统

[操作系统]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

//启动AD/activityA(19864): onCreateD/activityA(19864): onStartD/activityA(19864): onResume//启动BD/activityA(19864): onPauseD/activityB(19864): onCreateD/activityB(19864): onStartD/activityB(19864): onResumeD/activityA(19864): onStop//启动CD/activityB(19864): onPauseD/activityC(19864): onCreateD/activityC(19864): onStartD/activityC(19864): onResumeD/activityB(19864): onStop

然后按返回建:

D/activityC(19864): onPauseD/activityB(19864): onRestartD/activityB(19864): onStartD/activityB(19864): onResumeD/activityC(19864): onStopD/activityC(19864): onDestory

所以如果未调用onDestory重新启动的话,不会调用onCreate,而是会调用onRestart。

 

2、A->B->A

D/activityA(19864): onCreateD/activityA(19864): onStartD/activityA(19864): onResumeD/activityA(19864): onPauseD/activityB(19864): onCreateD/activityB(19864): onStartD/activityB(19864): onResumeD/activityA(19864): onStopD/activityB(19864): onPauseD/activityA(19864): onCreateD/activityA(19864): onStartD/activityA(19864): onResumeD/activityB(19864): onStop

修改A的启动模式为singleTop

->A->A

D/activityA(27075): onCreateD/activityA(27075): onStartD/activityA(27075): onResumeD/activityA(27075): onPauseD/activityA(27075): onNewIntentD/activityA(27075): onResume

->A->B->A

D/activityA(27075): onCreateD/activityA(27075): onStartD/activityA(27075): onResumeD/activityA(27075): onPauseD/activityB(27075): onCreateD/activityB(27075): onStartD/activityB(27075): onResumeD/activityA(27075): onStopD/activityB(27075): onPauseD/activityA(27075): onCreateD/activityA(27075): onStartD/activityA(27075): onResumeD/activityB(27075): onStop

当A不是栈顶时,启动A,又重新创建了A,而且观察以上输出,两个Activity切换时,首先当前Activity先onPause,然后被启动的Activity,依次onCreate, onStart, onResume显示出来之后,之前的Activity才会onStop。

修改A的启动方式为singleTask,

->A->A

D/activityA( 2744): onCreateD/activityA( 2744): onStartD/activityA( 2744): onResumeD/activityA( 2744): onPauseD/activityA( 2744): onNewIntentD/activityA( 2744): onResume

当A不存在时,创建A,当A存在且在栈顶时,先onPause,然后onNewIntent,之后onResume。

->A->B->A

D/activityA( 2744): onCreateD/activityA( 2744): onStartD/activityA( 2744): onResumeD/activityA( 2744): onPauseD/activityB( 2744): onCreateD/activityB( 2744): onStartD/activityB( 2744): onResumeD/activityA( 2744): onStopD/activityB( 2744): onPauseD/activityA( 2744): onNewIntentD/activityA( 2744): onRestartD/activityA( 2744): onStartD/activityA( 2744): onResumeD/activityB( 2744): onStopD/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): onCreateD/activityA(10578): onStartD/activityA(10578): onResumeD/activityA(10578): onPauseD/activityA(10578): onNewIntentD/activityA(10578): onResume

与singleTask表现一致

->A->B->A

D/activityA(10578): onCreateD/activityA(10578): onStartD/activityA(10578): onResumeD/activityA(10578): onPauseD/activityB(10578): onCreateD/activityB(10578): onStartD/activityB(10578): onResumeD/activityA(10578): onStopD/activityB(10578): onPauseD/activityA(10578): onNewIntentD/activityA(10578): onRestartD/activityA(10578): onStartD/activityA(10578): onResumeD/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): onCreateD/activityA(17860): onStartD/activityA(17860): onResumeD/activityA(17860): onPauseD/activityB(17860): onCreateD/activityB(17860): onStartD/activityB(17860): onResumeD/activityA(17860): onStop

生命周期的回调函数是完整的,都会依次调到,但是有个问题是当按back键后,会出现如下:

D/activityB(19588): onPauseD/activityA(19588): onRestartD/activityA(19588): onStartD/activityA(19588): onResumeD/activityA(19588): onPauseD/activityB(19588): onCreateD/activityB(19588): onStartD/activityB(19588): onResumeD/activityB(19588): onStopD/activityB(19588): onDestoryD/activityA(19588): onStop

需要返回A,但是A在启动的生命周期中又启动了B,这时的行为就跟启动模式有关了,总是它正常切换时正确的执行顺序。

 

这个知识点太绕了,其实万变不离其宗,都是四种启动模式生命周期执行顺序的组合。