假设他们的启动模式是标准的(不使用任何意图
旗帜)。 x 是应用 A 的 Main Activity; 1 是应用 B 的 Main Activity。
1) 启动应用 A,然后 x-> y -> 1,按主页按钮,启动应用 A
再次,我们会看到活动 y 还是 1?
您将看到活动1。您有一个包含x->y->1 的任务,该任务的活动堆栈顶部有活动1。当您按 HOME 时,此任务将移至后台。当您再次启动应用程序时,Android 会找到任务堆栈并将其(完整)带回前台,向您显示堆栈上的顶部活动(在本例中为 1)。
2) 启动应用程序 A 然后 x -> 1 -> y -> 2 -> z -> 3,按主页按钮,
启动应用程序 A,它将包含所有活动 (x -> 1 -> y -> 2 ->
z -> 3),还是只包含 x -> y -> z?
如上所述,您只有一个任务。当您按 HOME 时,任务包含 x->1->y->2->z->3 并移至后台。当您再次启动 App A 时,任务会被提前(完整),您会在顶部看到活动 3。
如果我们启动应用 B 怎么样
现在?应用 B 将包含哪些活动?
嗯,这样的问题是不正确的。您真正想知道的是“此任务将包含哪些活动?”,但答案如下:
如果您从主屏幕启动 App B,您将开始一个新任务。此任务将包含一个活动,即1。此任务与其他任务(仍在后台)无关。后台任务包含来自 2 个不同应用程序的活动这一事实无关紧要。
现在假设活动 1、2、3 是 SingleTask; x,y,z 仍然是标准:
3) 启动应用程序 A,然后 x -> y -> 1 -> 2,按主页按钮,启动应用程序
A,它将仅包含 x -> y 还是包含 x -> y -> 1 -> 2?
在活动y 启动活动1 时,这将创建一个新任务。因此,您将拥有一个包含活动x->y 的任务和另一个包含1 的任务。当活动1 启动活动2 时,会发生什么不仅仅取决于活动的launchMode。即使活动2 声明为launchMode="singleTask",如果活动2 的taskAffinity 与活动1 的taskAffinity 相同(默认情况下,如果它们属于同一应用程序)然后活动2将在与活动1相同的任务中创建(即:它的行为就像活动2具有launchMode="standard"一样)。但是,如果活动1 和活动2 具有不同的taskAffinity,则活动2 将作为新任务中的根活动启动。现在您将有 3 个任务,如下所示:Task1 包含 x->y,Task2 包含 1,Task3 包含 2。
如果我们现在启动应用 B 怎么样?应用 B 将仅包含 1 或 1 -> 2?
如上所述,这取决于taskAffinity。如果活动1和2的taskAffinity相同,则从HOME屏幕启动应用程序B会将包含1->2的任务带到前台。如果activity的taskAffinity不同,从HOME屏幕启动app B会将包含activity1的任务带到前台。
4) 启动应用 B,然后 1 -> 2 -> 3 -> 1,2 和 3 会被销毁吗?
没有。 2 和 3 不会被销毁。
假设1、2 和3 都具有launchMode="singleTask",那么它(再次)取决于taskAffinity 设置。假设所有活动都具有相同的taskAffinity,那么您将有一个包含1->2->3->1 的任务(您将有2 个活动实例1),因为taskAffinity 胜过launchMode。
如果所有活动都有不同的taskAffinity,那么在1->2->3 之后,您将有 3 个单独的任务,每个任务都包含一个活动。然后,当活动3 启动活动1 时,这只会将包含活动1 的任务带到前台,不会创建活动1 的新实例。
5) 启动应用 B,然后 1 -> 2 -> 3,按主页按钮,启动应用 A
现在,然后 x -> y -> 2 然后按后退按钮删除 2. 启动应用程序 B
现在,它包含哪些活动? 1 -> 仅 3 或 1 -> 2 -> 3?
同样,这取决于taskAffinity。如果应用 B 的所有活动都具有相同的taskAffinity,那么在1->2->3 之后,您将有一项任务。用户按下 HOME 按钮,此任务将进入后台。现在用户启动应用程序 A 创建一个新任务。在x->y 之后,第二个任务包含这两个活动。现在活动y 开始活动2。由于此活动具有launchMode="singleTask",并且与任务中的其他活动具有不同的taskAffinity(它们都具有App A 的taskAffinity),Android 将创建一个以活动2 为根的新任务。 Android 无法使用包含1->2->3 的现有任务,因为该任务不包含活动2 作为其根。当用户在2 中按下返回时,这将完成活动2,这将完成第三个任务,将用户返回到包含x->y 的第二个任务,活动y 在顶部。现在按 HOME 并启动应用程序 B 会将包含 1->2->3 的现有第一个任务带到前台。
但是,如果应用 B 的所有活动都有不同的taskAffinity,那么在1->2->3 之后,您将有 3 个单独的任务,每个任务都包含一个活动。用户按下 HOME 并启动 App A 创建一个新任务(现在您有 4 个任务)。在x->y 之后,第四个任务包含这两个活动。现在活动y 开始活动2。 Android 只是将包含活动2 的任务带到前台。用户按下 BACK 按钮,这将完成活动 2 和它所在的任务(因为该任务现在是空的),将用户返回到上一个任务,该任务是来自应用程序 A 的包含 x->y 的任务。启动应用程序 B 从主屏幕只会将包含活动1 的任务带到前台。您现在有 3 个任务:Task1 包含活动 1 并位于前台,Task2 包含活动 3 并位于后台,Task3 包含 x->y 并位于后台。
注意事项
我意识到这很复杂。我的回答是出自我的脑海,我并没有尝试实际实现所有这些组合并进行检查(但是,我过去已经实现了许多这样的案例,并且我确实知道它是如何工作的)。原因是您所描述的大部分内容在现实世界中都不会完成,因此这些示例仅是理论性的,并不实用。在现实生活中,您几乎不需要使用singleTask 或singleInstance 启动模式,除非您正在构建自己的主屏幕替代品,或者您需要仔细控制应用程序在其他应用程序启动时的行为方式 。在大多数情况下,您永远不会拥有多个启动模式为 singleTask 或 singleInstance 的活动。
如果您使用singleInstance 或singleTask,您需要了解taskAffinity 的工作原理,您还需要确保每个活动都有不同的应用程序图标(可能还有应用程序标签)声明为“singleTask”或“singleInstance”。否则,由于最近任务列表中的显示方式,用户将无法返回到正确的任务。