• 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,这时的行为就跟启动模式有关了,总是它正常切换时正确的执行顺序。

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

  • 相关阅读:
    python 各层级目录下的import方法
    Ubuntu更新python3.5到python3.7
    程序员的江湖--个人品牌
    产品经理看哪吒之魔童降世
    Python 相对路径和绝对路径--python实战(九)
    vim 下修改tab键为四个空格
    一个python问题引发的思考
    【python】多进程共享变量
    【python】spark+kafka使用
    【python】kafka在与celery和gevent连用时遇到的问题
  • 原文地址:https://www.cnblogs.com/zj2012zy/p/5331133.html
Copyright © 2020-2023  润新知