最近在开发中涉及到了启动模式相关的一些知识,干脆做个总结,方便以后查阅。
activity四种启动模式:standard 、singleTop、singleTask、singleInstance。每种启动模式的特点如下:
首先要有个总的思想: 每次启动一个activity,都是前者的onPause方法先执行,然后后者的onResume才执行。
1 standard: 系统默认模式。不管某个activity的实例是否存在,每次启动一个activity都会创建该activity的实例,典型的多实例实现模式。 注意:被启动的activity会运行在启动它的activity的任务栈中。 但这会引出一个问题: 假如我是用全局的context来启动的,那么系统就找不到被启动activity所需要的任务栈(何为所需要? 即:跟taskAffinity这个属性相关。默认就是该程序的包名,但是如果在某个activity的清单文件中给出了taskAffinity属性值,那么在启动该activity的时候,首先就会寻找是否有与手动设置的taskAffinity匹配的任务栈,如果有则加入到该栈中,反之,则加入到启动者的任务栈中),此时,我们需要在intent中设置一个标记位flag:FLAG_ACTIVITY_NEW_TASK。 此刻启动的activity实际上是以singleTask模式启动。
2, singelTop 栈顶复用模式。 当启动一个activity的时候,如果该activity的实例在栈顶位置已经存在,那么系统不会重新去创建了,会回调onNewIntent方法(这里有一点需要认识到:其实android本身就是监听者模式,每一个回调方法都要想到接口编程思想)。肯定的onCreate onStart方法也不会回调了。 反之,如果有实例但不在栈顶,那么系统还是会按照正常的流程去创建一个新的activity实例的。
3 singleTask 栈内复用模式。即是栈内单实例模式。我觉得应该从两个层面来理解:当以该模式来启动一个activity(A)的时候, 1 ,首先系统会寻找是否存在A想要的任务栈,如果没有,则会创建新的任务栈并创建A实例放入到栈中。2, 如果有,则要看该栈内是否已经有了A的实例,如果有A,则不会创建了,直接调用onNewIntent方法(注意:启动A 的时候,默认会把A上面的Activity全部出栈!!!!)。反之,则会创建A。
4,singleInstance 单实例模式。此时,activity A会被系统单独的放在一个新的任务栈中。 注意:是一个人在一个栈中。 此时,不管如何启动,系统都不会在创建A,栈内复用即可:回调onNewIntent方法。 只有该任务栈被销毁了,才会重新创建activity A.
taskAffinity 任务相关性
默认情况下,所有的activity所需任务栈的名字都是应用的包名。 如需手动设置,则需要taskAffinity配合singleTask或allowTaskReparenting属性配对使用,否则没有意义。
前两者搭配效果: 会在singleTask模式下创建 目前任务栈的名字的任务栈。
后两者搭配效果:A应用启动B应用中的一个C界面,如果Cactivity中的allowTaskReparenting为true时,C会加载到A应用的任务栈中(因为C所需的任务栈默认是B应用包名,所以此时,还是被加载到A应用任务栈中。),但,当B应用启动时,C会被系统从A任务栈转移到B任务栈中。此时,不会启动B的入口界面而是显示了C 界面。
常用的标记位:
FLAG_ACTIVITY_NEW_TASK 作用类似于singleTask启动模式,注意 两层意思!!
FLAG_ACTIVITY_SINGLE_TOP 类似于singleTop模式。
FLAG_ACTIVITY_CLEAR_TOP 该标记位需要注意: 如果是与singleTask一起时,则系统不会去重新创建该activity,只会把上面的activity清理掉。 而与standard模式一起时,则会把自己以及上面的activity都清理掉,然后在重新创建自己。所以,会有一闪的效果。数据也会重新初始化。
FLAG_ACTIVITY_ EXCLUDE_FROM_RECENTS 作用:从activity历史列表消失。 比如:我不希望用户通过回退列表再次回到某个activity的时候,就可以设置为true。
ok,暂时记录这么多。
新闻热点
疑难解答