Activity的启动模式

Activity的启动模式

参考自-Android开发艺术探索

为什么需要启动模式?在默认情况下,当我们多次启动同一个Activity的时候,系统会创建多个实例并把它们一一放入任务栈中,当我们单击back键,会发现这些Activity会一一回退。任务栈是一种“后进先出”的栈结构,这个比较好理解,每按一下back键就会有一个Activity出栈,直到栈空为止,当栈中无任何Activity的时候,系统就会回收这个任务栈。

在Android中,系统是利用任务栈来存储每次创建的Activity,这就意味着只要有多次重复调用同一个Activity的现象,那么我们就要创建多个Activity并且把他们存储到Activity中,这样不仅浪费存储空间,还使得Activity的回退机制变得过于死板,不符合Android灵活开发的需求。于是,Android对任务栈就行了一定的功能封装,形成了四种启动模式:

1.standard(标准模式)。
这是系统默认的启动模式。每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否已经存在。被创建的实例的生命周期符合典型情况下Activity的生命周期,这是一种典型的多实例实现,一个任务栈可以有多个实例,每个实例也可以属于不同的任务栈。在这种模式下,谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈中。比如Activity A启动了Activity B(B是标准模式),那么B就会进入到A所在的栈中。不知道读者是否注意到,当我们用ApplicationContext去启动standard模式的Activity的时候会报错。这是因为standard模式的Activity默认会进入启动它的Activity所属的任务栈中,但是由于非Activity类型的Context(如ApplicationContext)并没有所谓的任务栈,所以这就有问题了。解决问题的思路是为待启动Activity指定FLAG_ACTIVITY_NEW_TASK标记位,这样启动的时候就会为它创建一个新的任务栈,这个时候待启动Activity实际上是以singleTask模式启动的。

2.singleTop栈顶复用模式。
在这种模式下,如果要新建的Activity本身已经有一个Activity实例位于栈顶时,那么这个Activity不会被重新创建,而是会回调onNewIntent方法取出当前请求的信息。这个新建的Activity不会被系统调用onCreate、onStart方法,因为它并没有发生改变。如果新Activity的实例已经存在但不是位于栈顶,那么新Activity仍然会重新创建。

3.singTask栈内复用模式,这是一种单实例模式。
在这个模式下,只要Activity在任务栈中存在,那么当我们新建Activity时都不会重新创建实例,和SingleTop一样,系统也会回调onNewIntent。当一个具有singleTask模式的Activity请求启动后,比如Activity A,系统首先会寻找是否存在A想要的任务栈,如果不存在,就重新创建一个任务栈,然后创建A的实例后把A放到栈中。如果存在A所需的任务栈,这时要看A是否在栈中有实例存在,如果有实例存在,那么系统就会把A调到栈顶并调用它的onNewIntent方法,如果实例不存在,就创建A的实例并把A压入栈中。举几个例子:
(1)比如目前任务栈S1中的情况为ABC,这个时候Activity D以singleTask模式请求启动,其所需要的任务栈为S2,由于S2和D的实例均不存在,所以系统会先创建任务栈S2,然后再创建D的实例并将其入栈到S2。
(2)另外一种情况,假设D所需的任务栈为S1,其他情况如上面例子1所示,那么由于S1已经存在,所以系统会直接创建D的实例并将其入栈到S1。
(3)如果D所需的任务栈为S1,并且当前任务栈S1的情况为ADBC,根据栈内复用的原则,此时D不会重新创建,系统会把D切换到栈顶并调用其onNewIntent方法,同时由于singleTask默认具有clearTop的效果,会导致栈内所有在D上面的Activity全部出栈,于是最终S1中的情况为AD。

4.singleInstance(单实例模式)。
这是一种加强的singleTask模式,它除了具有singTask的一切特性之外,还加强了一点,就是具有此模式的Activity只能单独的位于一个任务栈中。也就是说,如果ActivityA是singleInstance模式,在它启动的时候,系统会为它分配一个新的任务栈。由于singleTask的复用性,在其他需要创建Activity的时候,都不会创建新的Activity。而注意的是,因为singleInsyance模式所创建的实例是位于一个独立的任务栈里,所以当我们销毁Activity的时候,会先把栈顶Activity所在的任务栈里面的Activity清理完毕再来清理该Activity。例如,Activity的启动顺序如下:
A(栈顶)
B(singleInstance)
C
D(栈底)
那么当我们连续按back键时,销毁顺序为 A -> C -> D -> B

你可能感兴趣的:(Android,Activity,启动模式)