Activity 与任务
任务(Task) 是一系列 Activity 的集合,本质上是一个管理多个 Activity 的堆栈。
当前 Activity 启动另一个 Activity 时,新的 Activity 将被推送到堆栈顶部;按返回按钮时,当前 Activity 又会从堆栈顶部退出(销毁),堆栈按照“后进先出”的对象结构运作。
当堆栈中所有的 Activity 都被移除后,该任务将不复存在。
在 Activity 中可通过以下方法查看当前任务信息:
public int getTaskId() // 获取当前 Activity 的任务对应的 id
public boolean isTaskRoot() // 返回当前 Activity 是否为所在任务的栈根
任务亲和性
“亲和性”表示 Activity 倾向于属于哪个任务。默认情况下,同一应用中的所有 Activity 彼此具有亲和性。因此,在默认情况下,同一应用中的所有 Activity 都倾向于位于同一任务。
可以使用 <activity>
元素的 taskAffinity
属性修改任何给定 Activity 的亲和性(未设置时默认值为应用包名)。
启动模式
Activity 的启动模式决定了一个新启动的 Activity 如何推入到目标任务栈中。可以通过两种方式定义不同的启动模式:
- 使用清单文件
- 使用 Intent 标记
清单文件配置启动模式
启动模式在可清单文件中通过 <activity>
元素的 launchMode
属性指定配置,共以下四种:
standard
- 默认。系统在启动该 Activity 的任务中创建 Activity 的新实例。
- 每个实例可以属于不同的任务,一个任务可以拥有多个实例。
singleTop
- 如果当前任务的栈顶已经是该 Activity 的实例,会通过调用该实例的 onNewIntent() 方法向其传送 Intent,而不是创建 Activity 的新实例;
- 未有实例或实例不在栈顶时,创建新的 Activity 实例入栈。
singleTask
- 若目标任务栈已存在(任务亲和性
taskAffinity
指定),切换该任务到前台;- 如果 Activity 实例已存在,把该实例以上的其他 Activity 全部弹出栈(销毁),并调用 onNewIntent() 方法;
- 如果 Activity 实例不存在,创建实例入栈顶;
- 若目标任务栈不存在,则系统会创建新任务,并实例化为新任务的根 Activity。
singleInstance
- 创建新任务并实例化为新任务的根 Activity;
- 系统不会将任何其他 Activity 启动到包含该实例的任务中,该 Activity 始终是其任务唯一的成员;
- 由该 Activity 启动的任何 Activity 都会在其他的任务中打开。
使用 Intent 标记
通过 Intent 标记(FLAG)可以灵活设置每次启动 Activity 时与任务的关联关系:
FLAG_ACTIVITY_NEW_TASK
- 若目标任务栈(任务亲和性
taskAffinity
指定)未存在,则系统会创建新任务,并实例化为新任务的根 Activity; - 若目标任务栈已存在且栈根为 Activity 的实例,则会把目标任务栈切到前台(不再创建实例,即便栈顶为其他 Activity);
- 如果栈根不为目标 Activity 的实例,则新建 Activity 的实例入栈(即便栈顶已是该 Activity 的实例)。
FLAG_ACTIVITY_SINGLE_TOP
- 与清单文件配置配置的
singleTop
启动模式表现相同。
FLAG_ACTIVITY_CLEAR_TOP
- 如果要启动的 Activity 已经在当前任务中运行,则把该实例以上的其他 Activity 全部弹出栈(销毁)。
- 当 launchMode 设置为
standard
且没有同时设置FLAG_ACTIVITY_SINGLE_TOP
,则该实例会被销毁然后重新创建。 - 当 launchMode 设置为其他的,或者同时设置了
FLAG_ACTIVITY_SINGLE_TOP
,当前实例会回调 onNewIntent() 方法。
FLAG_ACTIVITY_MULTIPLE_TASK
- 不与
FLAG_ACTIVITY_NEW_DOCUMENT
或FLAG_ACTIVITY_NEW_TASK
任意一个合用,这个标记将会失效; - 与
FLAG_ACTIVITY_NEW_TASK
一起使用时,会始终创建新的任务并实例化目标 Activity。
其他管理任务的属性
清单文件中 <activity>
元素还有以下一些属性可用于管理 Activity 与任务的关系:
allowTaskReparenting
-
当下一次将启动 Activity 的任务转至前台时,Activity 是否能从该任务转移至与其有相似性的任务。默认值为“false”。
-
正常情况下,Activity 启动时会与启动它的任务关联,并在其整个生命周期中一直留在该任务处。当不再显示现有任务时,可以使用该属性强制 Activity 将其父项更改为与其有相似性的任务。该属性通常用于将应用的 Activity 转移至与该应用关联的主任务。
alwaysRetainTaskState
- 如果在任务的根 Activity 中将该属性设为 “true”,则不会发生上述默认行为。即使经过很长一段时间后,任务仍会在其堆栈中保留所有 Activity。
clearTaskOnLaunch
- 如果在任务的根 Activity 中将该属性设为 “true”,那么只要用户离开任务再返回,堆栈就会被清除到只剩根 Activity。也就是说,它与 alwaysRetainTaskState 正好相反。用户始终会返回到任务的初始状态,即便只是短暂离开任务也是如此。
finishOnTaskLaunch
- 该属性与 clearTaskOnLaunch 类似,但它只会作用于单个 Activity 而非整个任务。它还可导致任何 Activity 消失,包括根 Activity。如果将该属性设为 “true”,则 Activity 仅在当前会话中归属于任务。如果用户离开任务再返回,则该任务将不再存在。