如何通过深度链接在不丢失活动堆栈(或应用程序状态)的情况下恢复 android 应用程序?

How to resume android app without losing activities stack (or the app state) with deep linking?

我有这个 <intent-filter> 每次按下某些 link 它都会打开我的应用程序但问题是它会打开我的应用程序的 new 实例. 有没有办法触发 onResume() 并在不丢失其状态或活动堆栈的情况下恢复我的应用程序?

这是意图过滤器:

        <intent-filter>
            <data android:scheme="http" />
            <data android:scheme="https" />
            <data android:host="example.com" />
            <data android:pathPattern="/.*" />

            <action android:name="android.intent.action.VIEW" />

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

更新

感谢用户 David Wasser 在下面的回答我找到了答案:

所以我创建了在 gmail/inbox app:

之上启动的 EntryActivity
public class EntryActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.entry_activity);

        Uri uriParams = getIntent().getData();

        Log.e("EntryActivity", uriParams.getHost() );
        Log.e("EntryActivity", uriParams.getQueryParameter("uid") + " " + uriParams.getQueryParameter("type") + " " + uriParams.getQueryParameter("token") );


        Intent startCategory = new Intent(this, GotEmailActivity.class);
        startCategory.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(startCategory);
        this.finish();
    }

}

然后当我的应用程序在 GotEmailActivity 打开时,我用 link 向用户发送电子邮件以打开应用程序并且 GotEmailActivity 在 AndroidManifest 中有属性 android:launchMode="singleTop" 所以只有它的 1 个实例被打开:

    <!-- 
        Important: notice android:launchMode="singleTop"
        which seeks if an instance of this activity is already opened and
        resumes already opened instance, if not it opens new instance.
     -->
    <activity
        android:name=".presenters.register.email.GotEmailActivity"
        android:label="@string/title_activity_got_email"
        android:launchMode="singleTop" 
        android:theme="@android:style/Theme.Translucent.NoTitleBar" >

现在发生的事情是 EntryActivity 在 Gmail 应用程序的顶部打开但它在中间关闭但首先启动已经打开的 GotEmailActivity 因此属性 launchMode Singletop 阻止了这样的新实例 activity.

您应该创建另一个 Activity,在响应 <intent-filter> 时用作应用程序的入口点。像这样:

您需要的只是一个什么都不做的简单 Activity。这是一个例子:

public class EntryActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Check to see if this Activity is the root activity
        if (isTaskRoot()) {
            // This Activity is the only Activity, so
            //  the app wasn't running. So start the app from the
            //  beginning (redirect to MainActivity)
            Intent mainIntent = getIntent(); // Copy the Intent used to launch me
            // Launch the real root Activity (launch Intent)
            mainIntent.setClass(this, MainActivity.class);
            // I'm done now, so finish()
            startActivity(mainIntent);
            finish();
        } else {
            // App was already running, so just finish, which will drop the user
            //  in to the activity that was at the top of the task stack
            finish();
        }
    }
}

将你的 <intent-filter> 放在这个 activity 上,而不是你的 "launcher" Activity。确保在清单中此 activity 的任务亲和力与应用程序中其他活动的任务亲和力相同(默认情况下,如果您没有明确设置 android:taskAffinity).

<intent-filter> 被触发时,如果您的应用程序是 运行,那么 EntryActivity 将在最顶层的 上启动activity 在您的应用程序的任务中,该任务将被带到前台。当 EntryActivity 完成时,它将简单地 return 用户到应用程序中的最顶层 activity (即:当它进入后台时用户离开的地方)。

如果您的应用 不是 运行EntryActivity 会识别这一点并从头启动您的应用,将其传递给 Intent包含触发 <intent-filter>.

的 ACTION 和 DATA

应该可以。