【问题标题】:How to keep a single activity instance but be able to update the view?如何保留单个活动实例但能够更新视图?
【发布时间】:2011-11-15 07:36:06
【问题描述】:

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

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

此活动由startActivityForResult 发起,我们将带有意图的 URI 发送给活动。

让我们讨论这个特定的案例:

  • 图库 - 使用 imageA 启动此活动。

  • 相机 - 使用 imageB 启动此活动。

我的要求不是销毁旧的activity,而是刚刚接收到新intent信息的activity应该刷新视图。


我发现了一个新方法,onNewIntent。 此方法可以在恢复之前刷新意图。我会试试的。

【问题讨论】:

  • 为什么活动保持活跃如此重要?我认为这是不可能的。
  • 这是因为如果有两个activity实例,会导致我们的应用出现问题。所以我需要确保它是单实例。

标签: android android-activity


【解决方案1】:

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

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

【讨论】:

  • 我的图像信息存储在 Intent 中。但我使用 getIntent() 获取的意图信息是旧的。也许这是关键问题。谢谢你的回复。
  • 有什么办法可以设置activity在哪个activity启动的taskactivity栈中。 ;此方法将使用该活动启动一个新任务。
  • 另一方面,“singleInstance”活动不允许其他活动成为其任务的一部分。这是任务中的唯一活动。因此,使用 android:launchMode="singleTask"。
【解决方案2】:

在您的清单中,使用android:launchMode="singleTask" 而不是android:launchMode="singleInstance"。使用 singleInstance 只会在现有实例位于堆栈顶部时返回它。 singleTask,另一方面,返回到活动的现有实例,因为它总是在任务的根。

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

详情请参考the Andorid documentation

【讨论】:

  • 我同意这两种模式只允许 Activity 的一个实例,但您对差异的解释是错误的。
  • @ben75 是对的:“singleTask”和“singleInstance”模式也仅在一个方面彼此不同:“singleTask”活动允许其他活动成为其任务的一部分。它始终位于其任务的根部,但其他活动(必须是“标准”和“singleTop”活动)可以启动到该任务中。另一方面,“singleInstance”活动不允许其他活动成为其任务的一部分。这是任务中的唯一活动。
【解决方案3】:

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

  • A(报名活动)
  • B(从A开始)
  • CsingleInstance,从B开始)

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

然而,如果我们启动A-&gt;B-&gt;C 然后按Home -> 应用程序转到后台。 现在有2种情况

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

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

另一种情况

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

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

另一个说明

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-06
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    • 1970-01-01
    • 2012-05-15
    • 2018-08-27
    相关资源
    最近更新 更多