知识总结: Activity的四种启动模式
通常情况下,一个应用有一个Task,这个Task就是为了完成某个工作的一系列Activity的集合。而这些Activity又被组织成了堆栈的形式。当一个Activity启动时,就会把它压入该Task的堆栈,而当用户在该Activity中按返回键,或者代码中finish掉时,就会将它从该Task的堆栈中弹出。然而,事实上我们的需求远没有我们想的那么简单。有时候,你可能希望在开启一个Activity时,重新开启一个Task;有时你可能希望将已经存在的一个Activity放到栈顶,而不是重新创建一个等等。
标识Activity任务栈名称的属性:TaskAffinity,默认为应用包名。
Android为了使我们能够打破默认的堆栈的先后出的模式,提供了两个种方式:一种是在AndroidManifest.xml定义Activity时指定它的加载模式,另一种是在用Intent开启一个Activity时,在Intent中加入标志。如果两种方式都用了,则后者的优先级更高。两种方式的差别在于,前者在于描述自己,向别的Acttivity等声明你们如何来加载我;而后者则是动态的,指出我要求你(要启动的Activity)如何来加载。
Android为我们定义了四种启动模式,分别是:standard、singleTop、singleTask和singleInstance。
1.standard加载模式下,当一个Task请求加载一个Activity时,该Task直接实例化这个Activity,并把它放到栈顶,不管之前栈中是否存在该Activity的实例。
2.singleTop加载模式时,当一个Task请求加载一个Activity时,如果该Task对应的栈的栈顶就是一个Activity的实例,那么,它便不会重新创建,而是调用onNewIntent。如果该Task对应的栈中Activity的实例存在,但不是在顶部,那么该Activity依然要重新创建。简单的说就是获得焦点的Activity(当前的Activity)不能再激活一个自己的实例呗。singleTop模式下的Activity可以被实例化多次,但是不可以多个相同的Activity的实例重叠。
3.singleTask加载模式时,当一个Task请求加载一个Activity时,如果该Task对应的栈中有一个Activity的实例,那么它便不会重新创建。如果已经实例化,会将Task中其上的Activity实例销毁后,调用onNewIntent。一句话,singleTask模式下的Activity,在自己的Task里只有一个实例,并且启动时不允许其他Activity凌驾于自己之上
4.在singleInstance这个模式下,当一个Task请求加载一个Activity时,如果所有Task的栈中有一个Activity的实例,那么,它便不会重新创建。如果所有Task的栈中没有一个Activity的实例,那么该Activity的实例被创建,并独占一个新的task,其它activity不能存在这个task里。
实例:
现在ATask的栈元素为A-B-C-D(D在栈顶),
这时候给D发起intent(D,D),
如果D是 “standard”的,则生成D的一个新实例,栈变为A-B-C-D-D;
如果D是singleTop的话,则不会生产D的新实例,栈状态仍为A-B-C-D;
如果这时候D发起intent(D,B)的话,不管B的launchmode是”standard” 还是 “singleTop” ,都会生成B的新实例,栈状态变为A-B-C-D-B;
如果B的launchmode是” singleTask”,栈状态变为A-B;
如果这时候D发起intent(D,E),E的launchmode是” singleInstance”,如果所有栈中不存在E,那么会产生一个新的Task栈,放入E,ATask的栈状态仍为A-B-C-D