一、启动模式
- standard(普通模式)
- singleTop(栈顶复用)
- singleTask(栈内复用、栈内唯一)
- singleInstance(独占新栈)
二、任务栈分配
普通情况下,没有设置 taskAffinity 属性的情况下
singleInstance独占一个栈,其他的都是共用一个栈
APP中指定ActivityB 的Affinity ,ActivityB 的栈会是什么情况的
它的栈分布情况完全取决于你同时使用的“启动模式”(launchMode)。taskAffinity 只是告诉系统:“如果需要新建任务栈,或者寻找复用栈时,请优先考虑这个名字(Affinity)对应的栈
情况一:ActivityB 是 standard 或 singleTop (默认情况)
结论:通常仍在主栈中,taskAffinity 几乎不起作用。
- 行为:
- 当你在主应用(Task A)中启动
ActivityB时,即使ActivityB配置了不同的taskAffinity,只要启动模式是standard或singleTop,系统默认还是会把它放入**当前调用者所在的任务栈(Task A)**中。 - 原因:这两种模式的设计初衷就是跟随调用者。
- 当你在主应用(Task A)中启动
- 例外(任务重父级 reparenting):
- 如果
ActivityB已经在另一个具有匹配 Affinity 的栈中存在,且应用配置了allowTaskReparenting="true",那么当应用回到前台时,ActivityB可能会从当前栈“跳”回它 affinity 对应的那个栈。但这属于特殊情况。
- 如果
- 栈分布:
- Task A:
[MainActivity, ..., ActivityB](混合在一起)
- Task A:
情况二:ActivityB 是 singleTask (最常见用法)
结论:会进入一个独立的、以该 Affinity 命名的任务栈。
这是 taskAffinity + singleTask 的经典组合,常用于将特定功能模块隔离。
- 行为:
- 系统检查是否存在一个
taskAffinity等于ActivityB所指定值的任务栈。 - 如果不存在:系统创建一个全新的任务栈(Task B),并将
ActivityB作为根 Activity 放入其中。 - 如果存在:系统将该栈拉到前台,并复用
ActivityB实例(清除其上方的 Activity)。
- 系统检查是否存在一个
- 栈分布:
- Task A (主栈):
[MainActivity, ...] - Task B (独立栈):
[ActivityB](或者[ActivityB, SubPage],如果在 B 里启动了其他 standard 页面且没改 affinity)
- Task A (主栈):
- 特点:
ActivityB拥有了自己的“地盘”。- 从
ActivityB启动其他standardActivity 时,这些新页面默认会进入 Task B(因为它们继承了ActivityB的 affinity),而不是回到 Task A。这可以实现整个功能模块的独立栈管理。
情况三:ActivityB 是 singleInstance
结论:必然进入一个独立的、独占的任务栈。
- 行为:
singleInstance强制要求独占栈。- 指定的
taskAffinity决定了这个独立栈的“逻辑名称”。 - 如果系统中已有相同 Affinity 的
singleInstance栈,则复用;否则新建。
- 栈分布:
- Task A:
[MainActivity, ...] - Task B:
[ActivityB](绝对独占,不能有其他 Activity)
- Task A:
- 注意:对于
singleInstance,即使不指定taskAffinity(使用默认包名),它也会因为模式特性而强制新建栈。指定 Affinity 主要是为了在多应用共享或特定场景下标识这个栈。
问题:
-
后续启动新的Activity 当
ActivityB是singleInstance模式并处于其独立的独占栈(假设为 Task B)中时,如果在ActivityB内部代码启动了一个新的standard模式的 Activity(假设为ActivityC):结论:
ActivityC绝对不会 进入ActivityB所在的 Task B。
它会被放入 调用者(ActivityB)原本所属的那个任务栈(通常是启动ActivityB的那个主栈,假设为 Task A),或者是一个与ActivityC的taskAffinity匹配的现有栈
核心总结表
ActivityB 配置
启动模式 (Launch Mode)
栈分布结果
解释
指定了 Affinity
standard / singleTop
通常在原栈
Affinity 被忽略,跟随调用者栈。除非发生任务重父级。
指定了 Affinity
singleTask
新建独立栈 (推荐)
系统会查找或创建一个与该 Affinity 匹配的新栈,B 成为栈底。
指定了 Affinity
singleInstance
新建独立栈 (独占)
强制新建独占栈,Affinity 作为该栈的标识。
问题:
由于 ActivityB 和 ActivityC 不在同一个栈,传统的 startActivityForResult (或新的 ActivityResultLauncher) 在这种跨栈场景下行为可能不符合预期,或者根本无法接收到结果,因为上下文(Context)所属的任务栈发生了切换,如何解决这个问题