【问题标题】:Android - URI Scheme - Stop from opening multiple instances of applicationAndroid - URI方案 - 停止打开多个应用程序实例
【发布时间】:2015-06-26 09:35:22
【问题描述】:

我正在使用自定义 URI 方案将用户从网站重定向到应用程序,但是在启动应用程序时,它会打开一个新实例,而不是仅仅恢复已经打开的实例。

我已经尝试过使用 launchMode="singleTask" 或 "singleInstance" 但它们似乎并没有影响它。

<!-- Splash. -->
    <activity
        android:launchMode="singleTask"

        android:name=".Activities.Splash"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="stateHidden"
        >

        <intent-filter>
            <data android:scheme="customscheme" />
            <action android:name="android.intent.action.VIEW"/>
            <category android:name="android.intent.category.BROWSABLE" />
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>

        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>


    </activity>

例子:

  1. 用户打开应用程序,从 Activity A 转到 Activity B。

  2. 用户打开网站,并通过 URI 被重定向回应用程序。

  3. 应用程序现在在 Activity A 上。

  4. 用户按下返回按钮,销毁 Activity A。

  5. 活动 B 现在来自第一个实例。

感谢您的时间和帮助!

【问题讨论】:

  • 第一:检查您是否没有选中“不保留活动”...第二:它会打开一个新实例...您如何确定关于这个?
  • 在哪里检查“不保留活动”?并且因为在使用应用程序时,按下后退按钮关闭应用程序只是关闭应用程序,并在其下方显示另一个。
  • 它是一些程序员/调试选项......你仍然写了活动 b 出现......活动是“下”它吗?
  • 第一次运行的活动 B 在第二次运行的活动 A 下。
  • 如果你错了怎么办......这是第一次运行的活动 a 刚刚移动到活动 B 前面......这就是为什么我问你为什么这么确定......跨度>

标签: android android-intent android-activity uri


【解决方案1】:

假设您没有为 Activity B 设置 android:taskAffinity,这是正确的做法。

  • 当您启动应用程序时,它会启动 ActivityA
  • ActivityA 将 ActivityB 启动到同一个任务中(即使您为 ActivityB 设置了launchMode="singleInstance",Android 也会忽略它,因为它与 ActivityA 具有相同的taskAffinity
  • 用户打开网站并被重定向回应用程序。 Android 将应用程序的现有任务(包含 ActivityA 和 ActivityB)带到前台,并创建 ActivityA 的新实例并将其置于现有活动之上。现在你有了一个 ActivityA -> ActivityB -> ActivityA 的任务栈。
  • 用户按下 BACK 按钮,完成堆栈顶部的 ActivityA 实例并显示下方的 ActivityB 实例。

如果您考虑一下,Android 无法打开现有的 ActivityA 实例,因为它被 ActivityB 覆盖。

有多种方法可以解决此问题,具体取决于您希望应用在不同情况下的行为方式。假设,如果应用程序已经在运行,您希望将任务堆栈清除回 ActivityA 的根实例,并且您希望重用该实例(而不是创建另一个实例)。最简单的方法之一是让 Web 浏览器打开另一个活动(不是 ActivityA),我们称之为 RedirectActivity 。这个新活动在其onCreate() 中有以下代码:

super.onCreate(...);
Intent intent = new Intent(this, ActivityA.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
finish();

此代码将执行以下操作之一,具体取决于...

  1. 如果应用尚未运行,它将创建一个新的 ActivityA 实例。
  2. 如果应用程序已经在运行,它将清除可能位于 ActivityA 现有实例之上的所有 Activity 的任务堆栈,然后它会返回到 ActivityA 的现有实例。

注意:还有其他可能合适的行为以及您可以使用其他技术来获得类似行为。

【讨论】:

  • 谢谢!你的解释很容易理解,我明白你在说什么。我使用了您的 RedirectActivity 代码,它运行良好。我将不得不对其进行更多研究,以获得更好的行为来实现我想要用它做的事情,但现在它工作得非常好。再次感谢您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 2018-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-11
相关资源
最近更新 更多