如何防止深层链接导致同一应用程序的多个实例?

Che*_*eng 2 android

抱歉,如果这似乎是一个重复的问题,因为深层链接导致应用程序的多个实例打开。但是,我认为从评论和答案中,如果没有适当的屏幕截图,我们大多数人都很难理解这个问题。

在您决定将其标记为重复之前,请允许我进一步详细说明这个问题。

有两种方法可以启动我的应用程序

  1. 通过点击应用程序图标
  2. 通过点击深层链接

我想要实现的是,无论我如何启动应用程序,无论是通过深层链接还是单击应用程序图标,我都希望任务列表中只显示 1 个应用程序实例。

但事实并非如此。请在下面查看我如何重现该问题。


第 1 步:点击应用程序图标

在此处输入图片说明

第 2 步:检查任务列表

在此处输入图片说明

第 3 步:启动 GMail 应用程序并查看任务列表

在此处输入图片说明

第 4 步:点击邮件中的深层链接,然后再次查看任务列表

在此处输入图片说明


正如您在任务列表中看到的那样。有 2 个 app 实例。最前面是使用深层链接调用的,最后是通过单击应用程序图标来调用的。

我尝试将以下技术结合使用,以确保任务列表中只有 1 个应用程序实例。

单顶

    <activity
        android:name=".JStockFragmentActivity"
        android:launchMode="singleTop"
        android:label="@string/title_activity_main" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

        <intent-filter android:autoVerify="true">
            <!-- Sets the intent action to view the activity -->
            <action android:name="android.intent.action.VIEW" />
            <!-- Allows the link to be opened from a web browser -->
            <category android:name="android.intent.category.BROWSABLE" />
            <!-- Allows the deep link to be used without specifying the app name -->
            <category android:name="android.intent.category.DEFAULT" />

            <!-- Accepts URIs that begin with "http://jstock.co/a/investing” -->
            <data android:scheme="http"
                android:host="jstock.co"
                android:pathPrefix="/a/investing" />

            <!-- Accepts URIs that begin with "https://jstock.co/a/investing” -->
            <data android:scheme="https"
                android:host="jstock.co"
                android:pathPrefix="/a/investing" />
        </intent-filter>
    </activity>
Run Code Online (Sandbox Code Playgroud)

isTaskRoot

/sf/answers/542389151/中提到了这种技术

public class JStockFragmentActivity extends AppCompatActivity implements GoogleApiClientFragment.ConnectionCallbacks {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        Utils.updateTheme(this);

        super.onCreate(savedInstanceState);

        // http://stackoverflow.com/questions/4341600/how-to-prevent-multiple-instances-of-an-activity-when-it-is-launched-with-differ
        //
        // Possible work around for market launches. See http://code.google.com/p/android/issues/detail?id=2373
        // for more details. Essentially, the market launches the main activity on top of other activities.
        // we never want this to happen. Instead, we check if we are the root and if not, we finish.
        //
        // The following code must be run after super.onCreate
        if (!isTaskRoot()) {
            final Intent intent = getIntent();
            final String intentAction = intent.getAction();
            if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) {
                Log.w(TAG, "Main Activity is not the root.  Finishing Main Activity instead of launching.");
                finish();
                return;
            }
        }
Run Code Online (Sandbox Code Playgroud)

但是,上述两种技术并不能阻止多个应用程序实例出现在任务列表中。

请问大家有没有遇到过类似的问题?您是否有一个好的解决方案来确保任务列表中只有 1 个应用程序实例?

Bar*_*rns 6

尝试将您的更改launchmodesingleTask.

Android 文档说:

系统在新任务的根创建活动并将意图路由到它。但是,如果 Activity 的实例已经存在,系统会通过调用其 onNewIntent() 方法将意图路由到现有实例,而不是创建一个新实例。

另一种解决方案可能是singleInstance. Android 文档说:

与“singleTask”相同,除了系统不会将任何其他活动启动到持有该实例的任务中。活动始终是其任务的唯一成员。