Android任务和进程,SingleTask和SingleInstance

8
我已阅读Google Android开发者页面,但任务的概念(http://developer.android.com/guide/components/tasks-and-back-stack.html)让我感到困惑。
当我阅读到SingleTask和SingleInstance时,我变得更加困惑了。
我想通过使用示例来提出一些问题,希望从这些问题中获得更好的理解:
假设我有两个应用程序A和B,A有x、y、z活动;B有1、2、3活动:
假设它们的启动模式是标准的(不使用任何意图标志)。而x是应用程序A的主要活动;1是应用程序B的主要活动。
1) 启动应用程序A,然后 x-> y -> 1,按Home键,再次启动应用程序A,我们会看到活动y还是1?

2) 启动应用程序A,然后x -> 1 -> y -> 2 -> z -> 3,按home按钮,再次启动应用程序A,它将包含所有活动(x -> 1 -> y -> 2 -> z -> 3),还是仅包含x -> y -> z?如果现在启动应用程序B呢?应用程序B将包含哪些活动?

现在假设活动1、2、3是SingleTask;x、y、z仍然是Standard:

3) 启动应用程序A,然后x -> y -> 1 -> 2,按home按钮,再次启动应用程序A,它将只包含x -> y还是包含x -> y -> 1 -> 2?如果现在启动应用程序B呢?应用程序B将只包含1还是包含1 -> 2?

4) 启动应用程序B,然后1 -> 2 -> 3 -> 1,2和3会被销毁吗?
5) 启动应用程序B,然后1 -> 2 -> 3,按Home按钮,现在启动应用程序A,然后x -> y -> 2,然后按返回按钮放弃2。现在启动应用程序B,它包含哪些活动?只有1 -> 3还是1 -> 2 -> 3?
感谢任何回复和帮助!
1个回答

16

If activities 1, 2, and 3 are SingleTask and x, y, z are Standard:

When you launch App A and navigate to x->y->1->2, the task now contains x->y->1->2 with activity 2 on top. When you press HOME, this task is moved to the background. When you launch App A again, Android finds the existing task stack and brings it (intact) back to the foreground. Since activities 1 and 2 are single task and already exist in the task stack, Android clears all activities on top of them and shows activity 2 on top. Therefore, you will see activities x->y->1->2.

当活动y启动活动1时,这将创建一个新任务。因此,您将有包含活动x->y的一个任务和包含1的第二个任务。当活动1启动活动2时,发生的情况取决于不仅是活动的launchMode,还包括其他因素。即使活动2声明为launchMode="singleTask",如果活动2taskAffinity与活动1taskAffinity相同(默认情况下,如果它们属于同一应用程序,则是这样),则活动2将在与活动1相同的任务中创建(即:它的行为就像活动2launchMode="standard")。但是,如果活动1和活动2具有不同的taskAffinity,那么活动2将在新任务中作为根活动启动。现在,您将有3个任务,如下所示:任务1包含x->y,任务2包含1,任务3包含2

如果现在启动应用程序B会怎样? 应用程序B只包含1还是1 -> 2?

与上述相同,这取决于taskAffinity。如果活动12taskAffinity相同,则从主屏幕启动应用程序B将使包含1->2的任务处于前台。如果活动的taskAffinity不同,则从主屏幕启动应用程序B将使包含活动1的任务处于前台。

4)启动应用程序B,然后1 -> 2 -> 3 -> 1,2和3会被销毁吗?

不会。 23不会被销毁。假设123都具有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,按Home键,现在启动应用程序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中按BACK时,这将完成活动2,从而完成第三个任务,将用户返回到包含x->y的第二个任务,并在顶部放置活动y。现在按HOME并启动应用程序B将使现有的第一个任务(包含1->2->3)前台显示。然而,如果应用程序B的所有活动都具有不同的“taskAffinity”,那么在1->2->3之后,您将拥有包含单个活动的三个单独任务。用户按HOME键并启动App A创建一个新任务(现在有4个任务)。在x->y之后,第四个任务包含这两个活动。现在活动y启动活动2。Android只是将包含活动2的任务置于前台。用户按BACK按钮,这会完成活动2以及它所在的任务(因为该任务现在为空),将用户返回到先前的任务,即包含来自应用程序A的x->y的任务。从主屏幕启动App B只会将包含活动1的任务置于前台。现在您有3个任务:Task1包含活动1并位于前台,Task2包含活动3并位于后台,Task3包含x->y并位于后台。
注: 我意识到这很复杂。我的答案来自我的头脑,我没有尝试实现所有这些组合并检查(但是,我过去实现了许多这些情况,并且确实知道它的工作原理)。原因是你描述的大部分内容在现实世界中不会被使用,因此这些示例仅是理论的而非实际的。在实际生活中,除非您正在构建自己的HOME屏幕替代品或需要仔细控制应用程序在被其他应用程序启动时的行为,否则您几乎永远不需要使用singleTask或singleInstance启动模式。在大多数情况下,您将永远不会有一个具有singleTask或singleInstance启动模式的活动超过一个。
如果您使用singleInstance或singleTask,则需要了解taskAffinity的工作方式,并确保每个声明为“singleTask”或“singleInstance”的活动都具有不同的应用程序图标(和可能还有应用程序标签)。如果没有,由于这些在最近任务列表中的显示方式,用户将无法返回到正确的任务。

1
这绝对是一个很好的答案!非常详细和完整!这是我第一次听说taskAffinitysingleTasksingleInstance中扮演如此重要的角色。非常感谢您的经验分享! - Sam YC
如果我从具有默认任务亲和性的应用程序中的A启动活动B,并使用标志ACTIVITY_NEW_TASK的意图,它会在与A相同的任务中启动活动B还是在不同的任务中启动? - pratim
4的答案是不正确的,2和3将被销毁(我已在模拟器中测试了这个问题)。 - floating cat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接