为什么行为不同?-android:launchMode =“ singleTask”,android:taskAffinity =“”和Intent.FLAG_ACTIVITY_NEW_TASK

zep*_*hyr 5 android launchmode back-stack

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

我以-> ABCDB的方式称呼这四个活动。(指定方式)

我有三种情况。

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

现在首先呼叫ABCD, BackStack Task 1 : A-B-C-D,

现在,我再次呼叫B,然后 BackStack Task 1 : A-B。这里的C和D活动被销毁。

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

现在首先呼叫ABCD, BackStack Task 1 : A

                                  Task 2 : B-C-D
Run Code Online (Sandbox Code Playgroud)

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

                                Task 2 : B ,Here C and D Activities are destroyed.
Run Code Online (Sandbox Code Playgroud)

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

现在首先呼叫ABCD, BackStack Task 1 : A

                                  Task 2 : B-C-D
Run Code Online (Sandbox Code Playgroud)

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

                                Task 2 : B-C-D , Here **Can't call B again**
Run Code Online (Sandbox Code Playgroud)

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

那么哪些是正确的方案?我做对了,或者我误会了一些东西。

Dav*_*ser 7

我已经复制了您所描述的行为。

第一种情况基本上没有记录,因为 asingleTask Activity应该始终是任务的根。由于 AndroidtaskAffinity在确定启动 的方式和位置时会使用Activity,因此您singleTask Activity将启动到现有任务中,而不是作为 root 启动Activity。这使得行为不同于记录的行为。当您启动BD,Android的需要交付IntentB到一个呼叫onNewIntent(),它不能做C,并D坐在上面B。所以Android的完成CD,然后调用onNewIntent()B

第二个场景显示您现在有 2 个任务,因为singleTask Activity以 root 身份启动到一个新任务中Activity。同样,当D启动时B,Android 需要通过调用来传递Intentto ,如果并且妨碍了它,它就无法做到。因此,Android 完成并交付到in 。BonNewIntent()CDCDIntentBonNewIntent()

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

谢谢你的挑战。

  • David Wasser,感谢您的详细回复。这是非常有用的。但我有一个问题。正如你所解释的第三种情况,>当 D 用 FLAG_ACTIVITY_NEW_TASK 启动 B 时,Android 会寻找一个以 B 作为根 Activity 的任务,如果找到,它会将这个任务带到前台,但不会将 Intent 传递给 onNewIntent() . > 但就我而言,当我在 D 之后再次呼叫 B 时,我似乎无法再次呼叫。它没有变成活动 B。它被困在活动 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` 将完成`D` 和`C` 并显示`B` 的现有实例,或者仅`Intent.FLAG_ACTIVITY_CLEAR_TOP` 将完成`D`、`C` 和`B`,然后启动一个新的“B”的实例。 (3认同)
  • 因此,总而言之, Intent.FLAG_ACTIVITY_NEW_TASK(仅单个属性)不会作为“单个任务”工作。谢谢你。正如您所描述的那样,它现在可以正常工作:-) (2认同)