如何保留单个活动实例但能够更新视图?

时间:2011-11-15 07:36:07

标签: android android-activity

在我的情况下,有一种情况我需要确保活动一次只运行一次。

我发现如果我设置了活动的LauchMode,我可以达到单个实例的目标,但它不会更新活动的视图。

此活动由startActivityForResult启动,我们会将意向的URI发送给活动。

让我们讨论一下这个案例:

  • 画廊 - 与imageA一起开展这项活动。

  • 相机 - 使用imageB进行此活动。

我的请求不是销毁旧活动,但刚收到新意图信息的活动应刷新视图。


我找到了一种新方法onNewIntent。 此方法可以在恢复之前刷新意图。我会尝试的。

3 个答案:

答案 0 :(得分:77)

您可以拥有一个manifest属性为singleInstance的Activity。 一旦重新启动活动,onResume就会被调用。您可以使用新图像更新视图,并使旧视图无效。

<activity ..
      android:launchMode= "singleInstance" />

答案 1 :(得分:35)

在您的清单中,使用android:launchMode="singleTask"代替android:launchMode="singleInstance"。使用 singleInstance 仅返回现有实例(如果它位于堆栈顶部)。另一方面, singleTask 返回活动的现有实例,因为它始终位于任务的根目录。

然后,当您的实例启动时,覆盖onNewIntent以根据新意图更新您的UI。

有关详细信息,请参阅the Andorid documentation

答案 2 :(得分:0)

在多个 Activity 应用程序中使用 android:launchMode="singleInstance" 时要小心。
这是我在 Pixel 4XL (Android 10) 上的测试
例如,我们有 3 个活动(没有声明 taskAffinity

  • A(进入活动)
  • B(从 A 开始)
  • CsingleInstance,从 B 开始)

如果我们开始 A->B->C。现在 A、B 在一个任务中,C 在一个不同的任务中。
从 C,按返回 -> 将看到 B,按返回 -> 将看到 A,按返回 -> 关闭应用程序。一切正常。

但是,如果我们启动 A->B->C 然后按 Home -> 应用程序转到后台。 现在有两种情况

  • 用户从“最近使用的应用”中再次打开应用。
    • 用户将看到C 屏幕。按返回 -> 应用将关闭(不要转到 B)
  • 用户通过点击应用图标再次打开应用
    • 用户将看到B 屏幕。按返回 -> 将看到 A,按返回 -> 应用将关闭(不要转到 C

两种情况下打开应用程序后的行为是不同的。但在这两种情况下,应用程序在 Recent 应用程序中始终可用,并且您永远无法从最近使用的应用程序中删除应用程序(删除后它会再次出现)。只能通过设置中的强制停止来删除它。
如果您运行 adb shell dumpsys activity activities,您将看到 Stack 中仍然存在 Activity,但您无法返回。

另一种情况

如果我们开始 A->B->C->A。现在 A、B、A 在一个任务中,C 在另一个任务中(A 当前对用户可见)。
从A,按返回-> 将看到B(不是C),按返回-> 将看到A,按返回-> 将看到C,按返回-> 应用程序将关闭。 (至少在这里我们可以回到C

现在,如果我们开始 A->B->C->A,然后按 Home。在这两种情况下,用户通过“最近”再次打开应用程序或单击应用程序图标,用户将看到一个屏幕。按返回 -> 将看到 B,按返回 -> 将看到 A,按返回 -> 应用程序将关闭(永远不会看到 C 屏幕)

另一个注意事项

上面的例子,虽然应用程序在 2 个任务上运行,但在 Recent apps 中,它只显示 1 个任务。 如果设置 taskAffinity,在 Recent apps 中,您将看到 2 个任务。在这种情况下,您可以选择包含要显示的活动的任务,但是当您按返回时,它只会返回相同任务中的活动或关闭应用程序(无法返回到另一个任务中的活动)。 此外,如果您再次点击应用图标打开应用,我们的行为与上述演示相同。

我认为 singleTasksingleTop 没有 singleInstance 复杂,因此如果足以解决您的问题,请考虑使用它们而不是 singleInstance