这是本人的第二个博客,上一篇我们讲到activity的生命周期,这一篇我们来讨论一下activity的四种加载模式。不知道怎么添加源码,希望大家见谅。
通常情况下,一个应用有一个Task,这个Task就是为了完成某个工作的一系列Activity的集合。这些Activity又被组织成了堆栈的形式。(栈是种先入后出的数据结构)
我们可以将activity理解成我们平时在家里面洗碗的过程,每个activity对应一个碗。当启动第一个activity的时候,就是将第一个碗放在那里,当启动了另外一个activity的时候,便将第二碗放在第一个碗的上面,就这样慢慢的堆积起来形成一个碗栈(task)。当我们按返回键的时候就会销毁这个activity,就是从这个碗栈里面把最上面的那个碗拿走,让下面的一个碗在最上面的过程。
看图:
然而,事实上我们的需求远没有我们想的那么简单。有时候,你可能希望在开启一个Activity时,重新开启一个Task;有时你可能希望将已经存在的一个Activity放到栈顶,而不是重新创建一个...那么我们怎样去操作和控制对应的taskactivity呢?
Android为了使我们能够打破默认的堆栈的先后出的模式,提供了两个种方式:一种是在AndroidManifest.xml定义Activity时指定它的加载模式,另一种是在用Intent开启一个Activity时,在Intent中加入标志。如果两种方式都用了,则后者的优先级更高。两种方式的差别在于,前者在于描述自己,向别的Acttivity等声明你们如何来加载我;而后者则是动态的,指出我要求你(要启动的Activity)如何来加载。
Android为我们定义了四种加载模式,分别是:standard、singleTop、singleTask和singleInstance。
1、standard模式:
这个模式也是Android 系统默认的模式,新产生的activity不管是自己还是别人,都会新建一个activity的实例,并把自己放到最上面的过程。用碗的概念来解释就是不管洗到什么碗都忘这个碗栈上面添加,不管是相同的碗还是说不相同的碗。(1->2 :表示1启动2)
比如activityA -> activityB -> activityC -> activityD -> activityE(A,B,C,D,E可以相同也可以不同)最后产生的task结果为:
2、singleTop模式
这个模式就是被启动的activity如何和当前位于栈顶的activity相同的话,它不会产生实例而是会调用onNewIntent()函数。如果被启动的activity不和当前位于栈顶的activity相同,便会产生新的activity的实例并将其位于栈顶。拿洗碗的例子来说就是,当放一个新碗放这个碗栈的时候,先看下当前碗栈最上面的那个是不是和这个新碗一样,是的话就不放进去(调用onNewIntent函数),如果不是的话就把新碗放在碗栈的栈顶。
举个例子:
activityA->activityB->activityC->activityC:
让我们来分析过程:activityA->activityB:因为B与A不同,产生栈AB
activityA->activityB->activityC:因为C与B不同,产生栈ABC
activityA->activityB->activityC->activityC:因为C与C相同,C调用一次onNewIntent函数,产生栈ABC
3、singleTask模式:
这个模式要分两种情况来分析。
(1)当在同一个应用程序中调用activity的时候(activityB申明为singleTask模式):
activityA->activityB->activityC->activityD->activityB:
下面来分析:A、activityA->activityB 得到的栈为 AB;按返回键:B->A
B、activityA->activityB->activityC 得到的栈为ABC;按返回键:C->B->A
C、activityA->activityB->activityC->activityD 得到的栈为ABCD;按返回键:D->C->B->A
D、activityA->activityB->activityC->activityD->activityB 得到的栈为AB(当task中已经有了B的时候,就会把B上面的实例(C,D)都销毁掉,把自己露出来)按返回键:B->A
(2)当别的程序调用了这个activity的时候(activityB申明为singleTask模式:)
activityA(第一个应用程序task9)->activityB(第二个应用程序:task10)->activityC(第二个应用程序:task10)->activityB(第二个应用程序:task10)->退回home->重新进入第一个应用程序(activityB消失,进入的是activityA)
下面来分析:
第一步:activityA(第一个应用程序task9)->activityB(第二个应用程序:task10) activityB产生新的task,并将B放入task10中;按返回键:B->A
第二步:activityA(第一个应用程序task9)->activityB(第二个应用程序:task10)->activityC(第二个应用程序:task10) 将activityC压入task10中;按返回键:C->B-A
第三步:activityA(第一个应用程序task9)->activityB(第二个应用程序:task10)->activityC(第二个应用程序:task10)->activityB(第二个应用程序:task10):销毁在task10中的activityC,显示task10中activityB;按返回键:B->A
第四步:activityA(第一个应用程序task9)->activityB(第二个应用程序:task10)->activityC(第二个应用程序:task10)->activityB(第二个应用程序:task10)->退回home->重新进入第一个应用程序(activityB消失,进入的是activityA)
再次进入第一个应用程序的时候,activityA已经不见了,直接显示task9中的activityA。按返回键:A->NULL
4、singleInstance模式:
这个模式就是将对应的activity单独放在一个task中,当被调用的时候如果没有该实例便新建一个放进新的task中,如果在task中有这个实例就直接取出来调用onNewIntent函数。
这个模式要分两种情况来分析。
(1)当在同一个应用程序中调用activity的时候(activityB申明为singleInstance模式):
activityA(task 9)->activityB(task10)->activityC(task9)->activityD(task9)->activityB(task10):
下面来进行分析:
第一步:activityA->activityB:activityB产生新的task10,并将activityB压入栈;按返回键:B->A
第二步:activityA(task 9)->activityB(task10)->activityC(task9):产生activityC,但是不压入task10,而是放入task9;按返回键:C->B->A
第三步:activityA(task 9)->activityB(task10)->activityC(task9)->activityD(task9):产生activityD,放入task9;按返回键:D->C->B->A
第四步:activityA(task 9)->activityB(task10)->activityC(task9)->activityD(task9)->activityB(task10):将task10中的那个activityB调出来,不产生新的activityB,同时还调用onNewIntent函数。按返回键:B->D->C->A
(2)当别的程序调用了这个activity的时候(activityB申明为singleInstance模式:)
activityA(第一个应用程序task9)->activityB(第二个应用程序:task10)->activityC(第二个应用程序:task11)->activityD(第二个应用程序:task11)-,>activityB(调用onnNewIntent函数)。返回键:B->D->C->A
下面借用http://winuxxan.blog.51cto.com/2779763/504047这篇博客来总结下这四个模式:
“拿来主义”standard模式。哪里需要调用我我就去哪里,可以多次实例化,可以几个相同的Activity重叠。
“拒绝堆叠”singleTop模式。可以多次实例化,但是不可以多个相同的Activity重叠,当堆栈的顶部为相同的Activity时,会调用onNewIntent函数。
“独立门户”singleTask模式。同一个应用中调用该Activity时,如果该Activity没有被实例化,会在本应用程序的Task内实例化,如果已经实例化,会将Task中其上的Activity销毁后,调用onNewIntent;其它应用程序调用该Activity时,如果该Activity没有被实例化,会创建新的Task并实例化后入栈,如果已经实例化,会销毁其上的Activity,并调用onNewIntent。一句话,singleTask就是“独立门户”,在自己的Task里,并且启动时不允许其他Activity凌驾于自己之上。
“孤独寂寞”singleInstance模式。加载该Activity时如果没有实例化,他会创建新的Task后,实例化入栈,如果已经存在,直接调用onNewIntent,该Activity的Task中不允许启动其它的Activity,任何从该Activity启动的其他Activity都将被放到其他task中,先检查是否有本应用的task,没有的话就创建。