Android - URI Scheme - Stop from opening multiple instances of application

时间:2015-06-26 09:35:22

标签: android android-intent android-activity uri

I'm using a custom URI scheme to redirect the user from a website to the application, but when launching the app, it opens a new instance instead of just restoring the already open one.

I have tried both using launchMode="singleTask" or "singleInstance" but they don't seem to affect it.

<!-- 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>

Example:

  1. User opens the application, from Activity A goes to Activity B .

  2. User opens website, and gets redirected back to app via URI.

  3. Application is now on Activity A.

  4. User presses back button, destroying Activity A.

  5. Activity B is now present from first instance.

Thanks for your time and help!

1 个答案:

答案 0 :(得分:2)

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

  • 启动应用时会启动ActivityA
  • ActivityA将ActivityB启动到同一任务中(即使您为ActivityB设置了launchMode="singleInstance",Android也会忽略它,因为它与ActivityA具有相同的taskAffinity
  • 用户打开网站并重定向回应用。 Android将应用程序(包含ActivityA和ActivityB)的现有任务带到前台,并创建ActivityA的新实例,并将其置于现有活动之上。现在你有一个ActivityA的任务堆栈 - &gt; ActivityB - &gt; 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现有实例之上的任何活动的任务堆栈,然后它将返回到ActivityA的现有实例。
  3. 注意:还有其他可能适合的行为以及可用于获得类似行为的其他技术。