像往常一样(叹气),文档是错误的。在您引用的图表中,显然 Activity Y 不能定义为 singleTask 并且是包含 2 个活动的后台任务中的顶级活动。
在测试具有特殊启动模式singleTask 和singleInstance 的场景时,请注意taskAffinity 在此行为中起着重要作用,因为taskAffinity 优先于特殊启动模式。
关于“任务”和“回栈”的区别:
“任务”是一组可以作为一个整体进行操作的活动。
- 当您启动应用程序时(假设它当前未运行),Android 会在前台创建一个新任务,其中包含您启动的应用程序的根 Activity。
- 当该活动开始新活动时,这些新活动将添加到当前任务中(通常情况下,尽管此行为有例外)。
- 当您按下 HOME 按钮时,当前任务将从前台移至后台。
- 当您显示“最近”列表时,显示的是最近任务列表,而不是最近活动列表或最近应用程序列表。
- 当您从最近的任务列表中选择一个任务时,如果该任务仍处于活动状态(其中仍有活动活动),则整个任务(包括其所有活动)将从后台带到前台。
- 任务也可以“堆叠”。当当前任务中的活动启动新任务中的活动时,新任务会堆叠在当前任务之上。这仅用于控制新任务完成时发生的情况。通常情况下,当新任务完成(其所有活动都已完成)时,Android 会将用户返回到上一个任务(即:开始完成任务的任务)。
“回栈”通常是指任务中的一组活动。每个任务都有自己的活动堆栈。这用于控制当前活动(位于后台堆栈顶部的活动)完成时会发生什么。通常,Android 会将用户返回到直接位于后堆栈中完成活动下方(下方)的活动。
Android 代码和文档经常提到任务的“根”(这是用于启动任务的 Activity)和任务的“顶部”或“前端”(这是目前正在显示)。
实际上,文档位于 :-( 这是一个示例:
相比之下,“singleTask”和“singleInstance”活动只能
开始一项任务。
这种说法通常是正确的,但并不总是正确的。例如,假设我有 2 个活动:A 和 B。 A 是启动活动(即:具有ACTION=MAIN 和CATEGORY=DEFAULT 的活动)并使用标准启动模式定义。 B 定义为 launchMode="singleTask"。我启动应用程序,Android 创建了一个A 的实例。然后在A 做:
startActivity(new Intent(this, B.class));
这将创建一个新的活动实例B 并将其放在同一任务中的A 之上。它不会创建以活动B 为根的新任务。原因是activityA和activityB具有相同的taskAffinity(默认情况下一个应用的所有activity都具有相同的taskAffinity),此时Android会忽略B的启动模式。
文档还说:
此外,设备一次只能保存一个活动实例
时间——只有一项这样的任务。
同样,taskAffinity 可以打破这种行为。再次假设我们有A、B 和C,它们都具有相同的(默认)taskAffinity。 A 和 C 具有标准启动模式,B 具有 launchMode="singleTask"。如果A 启动B,B 的实例不会在新任务中结束,而是在与A 相同的任务中(见上文)。现在B 开始C。 Android 创建C 的实例并将其放在同一任务中的B 之上。现在C打电话:
startActivity(new Intent(this, B.class));
Android 会创建一个 B 的新实例,并将其置于任务中的 C 之上。现在有 2 个 B 实例,它们都不是任务的根活动!这种行为也是因为taskAffinity 胜过启动模式。