1.2 Activity的启动模式
1.2.1Activity的LaunchMode
任务栈是一种“后进先出”的栈结构。
给Activity设置启动模式的主要目的就是为了解决,多次启动同一个Activity,系统会重复创建多个示例的问题。
-
standard:标准模式(系统默认的模式)
每次启动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标记位。
-
singleTop:栈顶复用模式。
如果新的Activity已经处于任务栈的栈顶,那么此时Activity不会被重新创建,同时它的onNewIntent方法会被回调。需要注意的是,这个Activity得onCreate、onStart不会被系统调用,因为它并没有发生改变。如果新的Activity的实例已经存在但不是位于栈顶,那么新的Activity任然会重建。
假设目前栈内的情况为ABCD,其中ABCD为四个Activity,A位于栈底,D位于栈顶,这个时候假设要再次启动D,如果D的启动模式为singleTop,那么栈内的情况仍然为ABCD;如果D的启动模式为standard,那么由于D被重新创建,导致栈内的情况变成ABCDD。
-
singleTask:栈内复用模式。
只要Activity在一个任务栈中,那么多次重复启动Activity都不会重新创建实例,系统会调用onNewIntent。
例如,当一个具有singleTask模式的Activity A请求启动了以后,系统会先寻找是否存在A想要的任务栈,如果不存在,就重新创建一个任务栈,然后创建A的实例并且把A放到栈中。如果存在A所需要的任务栈,这个时候需要判断A是否在栈中有实力存在,如果有实例存在,那么系统就会把A调到栈顶并且调用它的onNewIntent方法,如果实例不存在,就创建A的实例并把A压入栈中。
比如,目前任务栈S1中的情况为ABC,这个时候Activity D以singleTask模式请求启动,其所需要的任务栈为S2,由于S2和D的实例均不存在,所以系统会先创建任务栈S2,然后再创建D的实例并将其入栈到S2。
另外一种情况,假设D所需的任务栈为S1,其他情况如上面的例子1所示,那么由于S1已经存在,所以系统会直接创建D的实例并且将其入栈到S1。
如果D所需的任务栈为S1,并且当前任务栈S1的情况为ADBC,此时D并不会重新创建,系统会调用onNewIntent方法,同时singleTask默认具有clearTop的效果,会导致栈内所有在D上面的Activity全部出栈,于是S1的最终情况为AD。
具有clearTop效果。
-
singleInstance:单实例模式。
除了具有singleTask模式的所有特性意外,具有次模式的Activity能够单独地位于一个任务栈中。
-
TaskAffinity --- 任务相关性
这个参数表示了一个Activity所需要的任务栈的名字,默认情况下,所有Activity所需要的任务栈的名字为应用包的名字。
TaskAffinity属性,主要和singleTask启动模式或者allowTaskRearenting属性配对使用。
当TaskAffinity和singleTask启动模式配对使用的时候,它是具有该模式的Activity的目前任务栈的名字,待启动的Activity会运行在名字和TaskAffinity相同的任务栈中。
当TAskAffinity和allowTaskReparenting结合的时候,当应用A启动了应用B的某个Activity以后,如果这个Activity的allowTaskReparenting为true,那么当应用B被启动后,此Activity会直接从应用A的任务栈转移到应用B的任务栈中。
-
给Activity指定启动模式
AndroidMenifest
在Intent中设置标识位
区别:Intent中设置标识位优先于AndroidMenifest。