为啥行为不同?- android:launchMode="singleTask" , android:taskAffinity="" 和 Intent.FLAG

Posted

技术标签:

【中文标题】为啥行为不同?- android:launchMode="singleTask" , android:taskAffinity="" 和 Intent.FLAG_ACTIVITY_NEW_TASK【英文标题】:Why Behaviours are different ?- android:launchMode="singleTask" , android:taskAffinity="" And Intent.FLAG_ACTIVITY_NEW_TASK为什么行为不同?- android:launchMode="singleTask" , android:taskAffinity="" 和 Intent.FLAG_ACTIVITY_NEW_TASK 【发布时间】:2018-03-07 18:10:13 【问题描述】:

我有四个活动 - A、B、C、D

我以--> A-B-C-D-B 的方式称呼这四个活动。 (指定方式)

我有三个场景。

1st :- 我只在 B 活动中定义 android:launchMode="singleTask"。我正在以上述指定方式通过Intent 调用所有活动。

现在首先调用 A-B-C-D ,BackStack Task 1 : A-B-C-D,

现在我再次打电话给 B,然后是BackStack Task 1 : A-B。此处 C 和 D 活动被销毁。

第二个:- 我在 B 活动中定义 android:launchMode="singleTask"android:taskAffinity=""。我正在以上述指定方式通过Intent 调用所有活动。

现在首先调用 A-B-C-D ,BackStack Task 1 : A

                                  Task 2 : B-C-D

现在我再次打电话给 B,然后BackStack Task 1 : A

                                Task 2 : B ,Here C and D Activities are destroyed.

3rd :- 我在 B 活动中定义 Intent.FLAG_ACTIVITY_NEW_TASKandroid:taskAffinity=""。我正在以上述指定方式通过Intent 调用所有活动。

现在首先调用 A-B-C-D ,BackStack Task 1 : A

                                  Task 2 : B-C-D

现在我再次打电话给 B,然后BackStack Task 1 : A

                                Task 2 : B-C-D , Here **Can't call B again**

这里它说 FLAG_ACTIVITY_NEW_TASK 产生与“singleTask”相同的行为 - https://developer.android.com/guide/components/activities/tasks-and-back-stack.html

那么哪些是正确的场景?我做对了,或者我误解了一些东西。

【问题讨论】:

你在singleTasklaunchMode的活动中使用过onNewIntent()吗? 没有,我没用过。它的语法是什么?我的意思是 onNewIntent() 的语法 看看这个:***.com/a/12003146/5437621 但是,我没有在活动之间传递任何值,所以我应该强制重写 onNewIntent() 方法吗? 在初级阶段,我想知道上述场景的正确行为,这些正确与否? 【参考方案1】:

我已经重现了你所描述的行为。

第一种情况基本上没有记录,因为 singleTask Activity 应该始终是任务的根。因为 Android 在确定如何以及在何处启动 Activity 时使用 taskAffinity,所以您的 singleTask Activity 将被启动到现有任务中,而不是作为根 Activity。这使得行为不同于记录的行为。当您从D 启动B 时,Android 需要在对onNewIntent() 的调用中将Intent 传递给B,而对于CD 坐在B 之上则无法做到这一点.所以Android完成了CD,然后在B上调用onNewIntent()

第二个场景显示您现在有 2 个任务,因为 singleTask Activity 作为根 Activity 启动到一个新任务中。同样,当D 启动B 时,Android 需要通过调用onNewIntent()Intent 传递给B,如果CD 妨碍了它,它就无法做到这一点。所以Android完成CD然后将Intent传递给onNewIntent()中的B

第三个场景展示了FLAG_ACTIVITY_NEW_TASK的使用。当A 启动BFLAG_ACTIVITY_NEW_TASK 时,Android 会查找以B 作为根Activity 的现有任务。由于没有找到,它以根Activity 的身份在新任务中启动B。当D 使用FLAG_ACTIVITY_NEW_TASK 启动B 时,Android 会查找以B 作为根Activity 的任务,如果找到,它将将该任务带到前台但不交付IntentonNewIntent()。这只是将现有任务以其进入后台时所处的状态带到前台的一种方式。这就是你所看到的。这种行为也被记录(某种程度),但由于所有这些场景之间非常复杂的相互依赖关系,所有可能的情况都没有明确记录。有时您需要通过经验观察而不是阅读文档来发现其工作原理。

感谢您的挑战。

【讨论】:

David Wasser,感谢您的详细回复。这是非常有用的。但我有一个问题。正如您所解释的第三个场景,>当 D 使用 FLAG_ACTIVITY_NEW_TASK 启动 B 时,Android 会查找以 B 作为根 Activity 的任务,如果找到,它将将该任务带到前台,但不会将 Intent 传递给 onNewIntent() . >但就我而言,当我在 D 之后再次调用 B 时,我似乎无法再次调用。它没有更改为 Activity B。它卡在 Activity D 上。为什么会这样? 在第 3 个场景中,Android 将任务带到前台。该任务的根有B,但D 是最顶部的Activity,所以它是正在显示的那个。如果您真的想将B 放在顶部(以便显示),您需要使用Intent.FLAG_ACTIVITY_REORDER_TO_FRONT(将B 放在D 之上)或使用Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP将完成DC 并显示B 的现有实例,或者只显示Intent.FLAG_ACTIVITY_CLEAR_TOP 将完成DCB,然后启动B 的新实例。 因此,总而言之,Intent.FLAG_ACTIVITY_NEW_TASK(仅单个属性)不能作为“单个任务”工作。谢谢你。正如您所描述的,它现在可以正常工作了:-)

以上是关于为啥行为不同?- android:launchMode="singleTask" , android:taskAffinity="" 和 Intent.FLAG的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Object 和 var 变量的行为不同?

为啥 routerLink 和 router.navigate() 行为不同?

为啥 Java 创建的两个子进程行为不同?

为啥虚拟分配的行为与相同签名的其他虚拟功能不同?

为啥发布和调试模式下的代码行为不同?

为啥 MPMoviePlayerViewController 对相同的 URL 有不同的行为?