zoukankan      html  css  js  c++  java
  • Android动态设置启动模式

    在《Activity四大启动模式》 https://www.cnblogs.com/diyishijian/p/7705588.html 一文中,我们讲述了Activity的四种启动模式,并分析了每种启动模式的特点。

    在上述所有情况,都是我们在Manifest中设置的(通过launchMode属性设置),这个被称为静态设置(我们写程序写多了会发现有静态就有动态,而且静态多数在xml设置,动态在java代码设置),接下来我们来看一下如何动态设置Activity启动模式。

    注):如果同时有动态和静态设置,那么动态的优先级更高。

    1、关于动态设置与静态设置的理解:

      静态设置,可以理解为通知别人:就是当我被创建的时候,我告诉你我是通过这种模式启动的。

      动态设置,可以理解为别人的要求:别人给我设一个Flag,我就以这种Flag的方式启动。

      可能这个没什么用哈,但是仔细想一下这种对程序的思想理解应该是正确的。

    2、几种常见的Flag:

      我们说的动态设置,其实是通过Intent。

      如果我们要设置要启动的Activity的启动模式的话,只需要这样:

    intent.setFlags();

      然后在里面添加对应的Flag就好,那么接下来我们介绍几个常见的Flag(他的Flag太多了,头皮发麻。):

    2.1、_NEW_TASK

      它对应的Flag如下:

    Intent.FLAG_ACTIVITY_NEW_TASK

      这个Flag跟我们的singleInstance很相似:

      在给目标Activity设立此Flag后,会根据目标Activity的affinity进行匹配:

      如果已经存在与其affinity相同的task,则将目标Activity压入此Task。   

      反之没有的话,则新建一个task,新建的task的affinity值与目标Activity相同。然后将目标Activity压入此栈。

      其实简单来说,就是先看看需不需要创建一个新的Task,依据就是有没有相同的affinity。然后把Activity放进去。

      

      但是此情况和singleInstance有不同,有两点注意的地方:

    1. 新的Task没有说只能存放一个目标Activity。只是说决定是否新建一个Task。而singleInstance模式下新的Task只能放置一个目标Activity。
    2. 在同一应用下,如果Activity都是默认的affinity,那么此Flag无效。而singleInstance默认情况也会创建新的Task。

      这个东西理解起来可能有一些抽象,我们通过一个实例来证明他:

      首先,我们创建一个DynamicLaunchModeDemo项目,新建SecondActity、ThirdActivity,包括MainActivity在内的布局中都放置一个按钮,MainActiivty跳转SecondActivity,SecondActivity跳转ThirdActivity,ThirdActivity跳转SecondActivity。

      然后,我们需要创建一个新的App——TwoApp,这个App目前只需要一个MainActivity就够了,我们在MainActivity放置一个button,让他跳转到DynamicLaunchModeDemo的SecondActivity。

      我们点开TwoApp,现在只有TwoApp一个进程,然后点开DynamicLaunchModeDemo的SecondActivity,但是我们发现这时还是只有一个进程,

    TaskRecord{3110889 #40293 A=com.lyf.twoapp U=0 StackId=1 sz=2}
      Run #2: ActivityRecord{7b1a925 u0 com.lyf.dynamiclaunchmode/.SecondActivity t40293}
      Run #1: ActivityRecord{7c3623f u0 com.lyf.twoapp/.MainActivity t40293}

      现在我们在TwoApp的MainActivity跳转到DynamicLaunchModeDemo的SecondActivity的代码中添加_NEW_TASK的Flag。

    val intent = Intent()
    intent.action = "com.lyf.second"
    intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
    startActivity(intent)

      与上面不同的地方在于,我们新的界面创建在了新的进程中——其实就是DynamicLaunchModeDemo被唤醒了,我们来分析一下为什么会这样:

      首先我们会想一下我们上面所学过的一个东西,affinity:我们说这个东西在默认情况下就是App的包名packageName,而DynamicLaunchModeDemo中的SecondActivity默认的affinity就是DynamicLaunchModeDemo的包名。

      然后我们说_NEW_TASK情况下,会先查找是否有对应的affinity的task,如果有就不在创建,直接将其放入,反之新建task,所以新建的task就是我们的DynamicLaunchModeDemo的task.

      我们可以再做一个测试,我们先唤醒DynamicLaunchModeDemo,然后再让TwoApp跳转到DynamicLaunchModeDemo的SecondActivity(有点绕啊。。。),我们看是什么情况:

    TaskRecord{68b4826 #40317 A=com.lyf.dynamiclaunchmode U=0 StackId=1 sz=4}
      Run #5: ActivityRecord{d6350a7 u0 com.lyf.dynamiclaunchmode/.SecondActivity t40317}
    TaskRecord{b0812bd #40318 A=com.lyf.twoapp U=0 StackId=1 sz=1}
      Run #4: ActivityRecord{3a43927 u0 com.lyf.twoapp/.MainActivity t40318}
    TaskRecord{68b4826 #40317 A=com.lyf.dynamiclaunchmode U=0 StackId=1 sz=4}
      Run #3: ActivityRecord{e3c77a8 u0 com.lyf.dynamiclaunchmode/.ThirdActivity t40317}
      Run #2: ActivityRecord{5076832 u0 com.lyf.dynamiclaunchmode/.SecondActivity t40317}
      Run #1: ActivityRecord{1f5735f u0 com.lyf.dynamiclaunchmode/.MainActivity t40317}

      

      我们发现在TwoApp中唤醒DynamicLaunchModeDemo的SecondActivity,同样是被放入了DynamicLaunchModeDemo的默认Task中。

      此时activity的返回顺序是:SecondActivity->ThirdActivity->SecondActivity->MainActivity(TwoApp)->MainActivity(DynamicLaunchModeDemo)

    2.2、_SINGLE_TOP

      该模式比较简单,对应Flag如下:

    Intent.FLAG_ACTIVITY_SINGLE_TOP

      此Flag与静态设置中的singleTop效果相同

    2.3、_CLEAR_TOP

      这个模式对应的Flag如下:

    Intent.FLAG_ACTIVITY_CLEAR_TOP

      

      当设置此Flag时,目标Activity会检查Task中是否存在此实例,如果没有则添加压入栈,

      如果有,就将位于Task中的对应Activity其上的所有Activity弹出栈,此时有以下两种情况:

    1. 如果同时设置Flag_ACTIVITY_SINGLE_TOP,则直接使用栈内的对应Activity,
    2. 没有设置。。。。。。。,则将栈内的对应Activity销毁重新创建。

      

      关于这个Flag,我们发现他和singleTask很像,准确的说,是在_CLEAR_TOP和_SINGLE_TOP同时设置的情况下,就是singleTask模式。

      而唯一不同的一点就在于:他会销毁已存在的目标实例,再重新创建。这个我们通过打印一下生命周期就好。

      这次我们只用DynamicLaunchModeDemo就好了,还是1->2,2->3,3->2,这次我们将2的Flag设置为_CLEAR_TOP,看一下SecondActivity的生命周期。

      

    2020-04-28 19:39:05.914 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onCrate: MainActivity taskId: 40371 hashCode: 240613018
    2020-04-28 19:39:05.915 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: taskAffinity: com.lyf.dynamiclaunchmode
    2020-04-28 19:39:05.936 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onStart: MainActivity taskId: 40371 hashCode: 240613018
    2020-04-28 19:39:05.943 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onResume: MainActivity taskId: 40371 hashCode: 240613018

    2020-04-28 19:39:08.317 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onPause: MainActivity taskId: 40371 hashCode: 240613018
    2020-04-28 19:39:08.350 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onCrate: SecondActivity taskId: 40371 hashCode: 18253684
    2020-04-28 19:39:08.351 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: taskAffinity: com.lyf.dynamiclaunchmode
    2020-04-28 19:39:08.359 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onStart: SecondActivity taskId: 40371 hashCode: 18253684
    2020-04-28 19:39:08.364 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onResume: SecondActivity taskId: 40371 hashCode: 18253684
    2020-04-28 19:39:08.709 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onStop: MainActivity taskId: 40371 hashCode: 240613018

    2020-04-28 19:39:14.335 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onPause: SecondActivity taskId: 40371 hashCode: 18253684
    2020-04-28 19:39:14.370 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onCrate: ThirdActivity taskId: 40371 hashCode: 152801606
    2020-04-28 19:39:14.371 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: taskAffinity: com.lyf.dynamiclaunchmode
    2020-04-28 19:39:14.378 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onStart: ThirdActivity taskId: 40371 hashCode: 152801606
    2020-04-28 19:39:14.383 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onResume: ThirdActivity taskId: 40371 hashCode: 152801606
    2020-04-28 19:39:14.712 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onStop: SecondActivity taskId: 40371 hashCode: 18253684

    2020-04-28 19:39:17.524 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onPause: ThirdActivity taskId: 40371 hashCode: 152801606
    2020-04-28 19:39:17.530 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onDestroy: SecondActivity taskId: 40371 hashCode: 18253684
    2020-04-28 19:39:17.567 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onCrate: SecondActivity taskId: 40371 hashCode: 183077611
    2020-04-28 19:39:17.568 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: taskAffinity: com.lyf.dynamiclaunchmode
    2020-04-28 19:39:17.575 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onStart: SecondActivity taskId: 40371 hashCode: 183077611
    2020-04-28 19:39:17.579 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onResume: SecondActivity taskId: 40371 hashCode: 183077611
    2020-04-28 19:39:17.953 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onStop: ThirdActivity taskId: 40371 hashCode: 152801606
    2020-04-28 19:39:17.959 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onDestroy: ThirdActivity taskId: 40371 hashCode: 152801606

    2020-04-28 19:39:45.142 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onPause: SecondActivity taskId: 40371 hashCode: 183077611
    2020-04-28 19:39:45.174 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onCrate: ThirdActivity taskId: 40371 hashCode: 245889006
    2020-04-28 19:39:45.175 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: taskAffinity: com.lyf.dynamiclaunchmode
    2020-04-28 19:39:45.182 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onStart: ThirdActivity taskId: 40371 hashCode: 245889006
    2020-04-28 19:39:45.186 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onResume: ThirdActivity taskId: 40371 hashCode: 245889006
    2020-04-28 19:39:45.519 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onStop: SecondActivity taskId: 40371 hashCode: 183077611

    2020-04-28 19:39:52.680 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onPause: ThirdActivity taskId: 40371 hashCode: 245889006
    2020-04-28 19:39:52.686 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onDestroy: SecondActivity taskId: 40371 hashCode: 183077611
    2020-04-28 19:39:52.720 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onCrate: SecondActivity taskId: 40371 hashCode: 131592179
    2020-04-28 19:39:52.721 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: taskAffinity: com.lyf.dynamiclaunchmode
    2020-04-28 19:39:52.729 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onStart: SecondActivity taskId: 40371 hashCode: 131592179
    2020-04-28 19:39:52.734 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onResume: SecondActivity taskId: 40371 hashCode: 131592179
    2020-04-28 19:39:53.103 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onStop: ThirdActivity taskId: 40371 hashCode: 245889006
    2020-04-28 19:39:53.105 28424-28424/com.lyf.dynamiclaunchmode I/LaunchMode: onDestroy: ThirdActivity taskId: 40371 hashCode: 245889006

    TaskRecord{b0aa9bb #40371 A=com.lyf.dynamiclaunchmode U=0 StackId=1 sz=2}
        Run #2: ActivityRecord{6c1182b u0 com.lyf.dynamiclaunchmode/.SecondActivity t40371}
        Run #1: ActivityRecord{3fa58be u0 com.lyf.dynamiclaunchmode/.MainActivity t40371}

      从日志可以看出3->2的时候,2先销毁再创建,3最后也会销毁。

      现在我们同时加上_SINGLE_TOP的Flag,效果相同,我们看Log

    2020-04-28 19:47:45.180 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onCrate: MainActivity taskId: 40377 hashCode: 240613018
    2020-04-28 19:47:45.181 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: taskAffinity: com.lyf.dynamiclaunchmode
    2020-04-28 19:47:45.203 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onStart: MainActivity taskId: 40377 hashCode: 240613018
    2020-04-28 19:47:45.209 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onResume: MainActivity taskId: 40377 hashCode: 240613018

    2020-04-28 19:47:47.832 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onPause: MainActivity taskId: 40377 hashCode: 240613018
    2020-04-28 19:47:47.878 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onCrate: SecondActivity taskId: 40377 hashCode: 18253684
    2020-04-28 19:47:47.878 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: taskAffinity: com.lyf.dynamiclaunchmode
    2020-04-28 19:47:47.886 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onStart: SecondActivity taskId: 40377 hashCode: 18253684
    2020-04-28 19:47:47.891 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onResume: SecondActivity taskId: 40377 hashCode: 18253684
    2020-04-28 19:47:48.240 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onStop: MainActivity taskId: 40377 hashCode: 240613018

    2020-04-28 19:47:49.903 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onPause: SecondActivity taskId: 40377 hashCode: 18253684
    2020-04-28 19:47:49.935 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onCrate: ThirdActivity taskId: 40377 hashCode: 27622280
    2020-04-28 19:47:49.936 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: taskAffinity: com.lyf.dynamiclaunchmode
    2020-04-28 19:47:49.943 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onStart: ThirdActivity taskId: 40377 hashCode: 27622280
    2020-04-28 19:47:49.948 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onResume: ThirdActivity taskId: 40377 hashCode: 27622280
    2020-04-28 19:47:50.275 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onStop: SecondActivity taskId: 40377 hashCode: 18253684

    2020-04-28 19:47:52.160 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onPause: ThirdActivity taskId: 40377 hashCode: 27622280
    2020-04-28 19:47:52.168 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onNewIntent: SecondActivity taskId: 40377 hashCode: 18253684
    2020-04-28 19:47:52.168 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: taskAffinity: com.lyf.dynamiclaunchmode
    2020-04-28 19:47:52.169 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onRestart: SecondActivity taskId: 40377 hashCode: 18253684
    2020-04-28 19:47:52.171 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onStart: SecondActivity taskId: 40377 hashCode: 18253684
    2020-04-28 19:47:52.172 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onResume: SecondActivity taskId: 40377 hashCode: 18253684
    2020-04-28 19:47:52.513 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onStop: ThirdActivity taskId: 40377 hashCode: 27622280
    2020-04-28 19:47:52.515 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onDestroy: ThirdActivity taskId: 40377 hashCode: 27622280

    2020-04-28 19:48:11.278 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onPause: SecondActivity taskId: 40377 hashCode: 18253684
    2020-04-28 19:48:11.313 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onCrate: ThirdActivity taskId: 40377 hashCode: 255683519
    2020-04-28 19:48:11.313 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: taskAffinity: com.lyf.dynamiclaunchmode
    2020-04-28 19:48:11.320 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onStart: ThirdActivity taskId: 40377 hashCode: 255683519
    2020-04-28 19:48:11.325 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onResume: ThirdActivity taskId: 40377 hashCode: 255683519
    2020-04-28 19:48:11.661 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onStop: SecondActivity taskId: 40377 hashCode: 18253684

    2020-04-28 19:48:13.284 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onPause: ThirdActivity taskId: 40377 hashCode: 255683519
    2020-04-28 19:48:13.291 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onNewIntent: SecondActivity taskId: 40377 hashCode: 18253684
    2020-04-28 19:48:13.292 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: taskAffinity: com.lyf.dynamiclaunchmode
    2020-04-28 19:48:13.293 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onRestart: SecondActivity taskId: 40377 hashCode: 18253684
    2020-04-28 19:48:13.295 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onStart: SecondActivity taskId: 40377 hashCode: 18253684
    2020-04-28 19:48:13.296 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onResume: SecondActivity taskId: 40377 hashCode: 18253684
    2020-04-28 19:48:13.632 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onStop: ThirdActivity taskId: 40377 hashCode: 255683519
    2020-04-28 19:48:13.633 29327-29327/com.lyf.dynamiclaunchmode I/LaunchMode: onDestroy: ThirdActivity taskId: 40377 hashCode: 255683519

    TaskRecord{18250ba #40377 A=com.lyf.dynamiclaunchmode U=0 StackId=1 sz=2}
        Run #2: ActivityRecord{597cf08 u0 com.lyf.dynamiclaunchmode/.SecondActivity t40377}
        Run #1: ActivityRecord{f85527f u0 com.lyf.dynamiclaunchmode/.MainActivity t40377}

      很明显,在3->2的时候,TwoActivity调用了onRestart方法,也就是栈顶复用了。

      

  • 相关阅读:
    14. Longest Common Prefix
    7. Reverse Integer
    用例图是软件项目成本预估的好帮手
    设计模式之创建性模式
    代码的核心定义文件
    一个项目经理的经验总结
    设计模式之结构型模式
    互联网发展十几年,你错过了哪些创业机会
    产品经理必读:像怀胎一样怀产品,要厚着脸皮听批评
    陌陌估值1亿美元:一个用户10美元,贵吗?
  • 原文地址:https://www.cnblogs.com/diyishijian/p/12796806.html
Copyright © 2011-2022 走看看