启动模式
顾名思义,Activity启动的方式,会影响Activity在任务栈中的行为。
主要有以下四种模式:
- standard(默认方式)
- singleTop
- singleTask
- singleInstance
启动模式在AndroidManifest.xml
文件的activity标签中设置
<activity
android:name=".DemoActivity"
android:launchMode="standard" />
standard
标准模式,Activity的默认启动模式。
以此种模式启动的Activity会直接放到启动该Activity任务栈的栈顶,并且在该任务栈中可拥有多个实例。
singleTop
栈顶复用模式
以此种模式启动的Activity会先判断启动该Activity任务栈的栈顶是否存在该Activity的实例,若栈顶存在实例,则不创建该Activity的实例,直接调用该Activity实例的onNewIntent()方法将Intent传递给该实例。否则创建此Activity实例,并将其放到启动该Activity任务栈的栈顶。此模式启动下的Activity可以在任务栈中拥有多个实例,只要实例不在栈顶即可。
singleTask
栈内复用模式
以此种模式启动的Activity会先判断该Activity的目标任务栈中是否存在该Activity的实例,若栈中存在实例,则不创建该Activity的实例,直接调用该Activity实例的onNewIntent()方法将Intent传递给该实例,并且将该Activity之上的Activity实例全部清除。否则创建此Activity实例,并将其放到目标任务栈中。若该Activity的目标任务栈不存在,则创建任务栈,并且实例化该Activity放入目标栈中。此模式启动下的Activity在目标任务栈中只能拥有一个实例。
singleInstance
单实例模式
以此种模式启动的Activity会先判断该Activity的目标任务栈是否存在
- 若栈存在但不存在该Activity的实例,则创建一个新的目标任务栈,并且创建该Activity的实例放入栈中。
- 若栈存在且存在该Activity的实例,则不再创建新的实例,直接调用存在实例的onNewIntent()方法。
- 若目标任务栈不存在,则创建栈并创建该Activity的实例放入栈中。
此模式启动下的Activity在目标任务栈中只能拥有此Activity一个实例,不能存在其他Activity。
TaskAffinity
处理亲和性
这是谷歌官方的叫法,我更倾向于解释为上文提及的目标任务栈。
“亲和性”表示 Activity 倾向于属于哪个任务。默认情况下,同一应用中的所有 Activity 彼此具有亲和性。因此,在默认情况下,同一应用中的所有 Activity 都倾向于位于同一任务。不过,您可以修改 Activity 的默认亲和性。在不同应用中定义的 Activity 可以具有相同的亲和性,或者在同一应用中定义的 Activity 也可以被指定不同的任务亲和性。
TaskAffinity在AndroidManifest.xml
文件的activity标签中设置
<activity
android:name=".DemoActivity"
android:taskAffinity="cn.jeamotu" />
TaskAffinity默认为应用的包名。
Intent FLAGS
常用的标志符有以下三种
- FLAG_ACTIVITY_NEW_TASK
- FLAG_ACTIVITY_SINGLE_TOP
- FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_NEW_TASK
- 通常使用时需配合taskAffinity使用,效果等同于singleTask的启动模式,若不刻意设置taskAffinity,效果等同于standard的启动模式
- 特殊情况下使用,在Activity之外启动Activity(Service、BroadcastReceiver)时需要加此Flag,否则会报异常
FLAG_ACTIVITY_SINGLE_TOP
效果等同于singleTop的启动模式
FLAG_ACTIVITY_CLEAR_TOP
如果要启动的 Activity 已经在当前任务中运行,则不会启动该 Activity 的新实例,而是会销毁位于它之上的所有其他 Activity,并通过 onNewIntent() 将此 intent 传送给它的已恢复实例(现在位于堆栈顶部)。
FLAG_ACTIVITY_CLEAR_TOP 最常与 FLAG_ACTIVITY_NEW_TASK 结合使用。将这两个标记结合使用,可以查找其他任务中的现有 Activity,并将其置于能够响应 intent 的位置。
注意:如果指定 Activity 的启动模式为 "standard",系统也会将其从堆栈中移除,并在它的位置启动一个新实例来处理传入的 intent。这是因为当启动模式为 "standard" 时,始终会为新 intent 创建新的实例。