在《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有不同,有两点注意的地方:
- 新的Task没有说只能存放一个目标Activity。只是说决定是否新建一个Task。而singleInstance模式下新的Task只能放置一个目标Activity。
- 在同一应用下,如果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弹出栈,此时有以下两种情况:
- 如果同时设置Flag_ACTIVITY_SINGLE_TOP,则直接使用栈内的对应Activity,
- 没有设置。。。。。。。,则将栈内的对应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方法,也就是栈顶复用了。