Android 通知启动 activity 的新实例,无论 launchMode and/or 标志设置成什么

Android notification starting new instance of activity no matter what the launchMode and/or flags are set to

我对此进行了大量研究,但遇到了瓶颈。我已经阅读了关于该主题的所有 material 内容(包括 this, this, and this 以及文档),但没有任何内容可以帮助我完成我想做的事情。

基本上,如果应用程序在用户的 phone 上打开,我只需要一个通知将用户重定向到我的应用程序中已经存在的 Activity。我使用这样的模式:

private PendingIntent buildPendingIntentForNotification(String type) {
        Intent resultIntent = new Intent(this, MainActivity.class);
        resultIntent.setAction(Intent.ACTION_VIEW);
        resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);// have tried without this and with Intent.FLAG_ACTIVITY_CLEAR_TOP
        resultIntent.putExtra(CommonUtils.NOTIFICATION_TYPE, type);
        PendingIntent resultPendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        return resultPendingIntent;
    }

我还尝试在 activity 标签内的 Android 清单中声明所有 4 种类型的启动模式。无论我做什么,点击通知(即使该应用程序是屏幕上的活动前台应用程序并且 MainActivity 是活动的 activity)似乎总是从重新启动 activity在创建。从我在调试过程中看到的情况来看,在获取通知和单击通知之间的任何时间都不会调用 onDestroy。但是,点击通知后,调用 onCreate 然后调用 onDestroy,即使我的 activity 没有被销毁,这很奇怪。我希望有人可以帮助我理解这一点,因为所有的 launchMode 和 Intent.setFlags 建议都不适合我。非常感谢!

您无法控制也无法确定 Android 上的 state of your activities,这意味着(在您的上下文中)您只能启动已暂停的 activity 而不是暂停的 activity已被摧毁。 OS 决定哪些活动将保持暂停状态,哪些活动将被破坏,您无法控制。当您的 activity 离开前台时,将在未定义的时间调用连续的回调,并调用 OS 的

您可以简单地做的是将 activity 的实例状态保存在 onPause() 方法中(我们确信一旦 activity离开前景)并在 onCreate() 上,您可以使用以前的数据恢复 activity。

注意:如果您有 Activity A 和 activity B 并且您从 activity B 开始27=] A,然后在 activity BonCreate() 方法上你可以 getIntent().getExtras()

有两种方法可以做到这一点:

  1. Notification to restore a task rather than a specific activity?

  2. Resume application and stack from notification

但是,您可能还会看到这个 nasty Android bug

仅供参考,这是我用来解决问题的代码(感谢 David 的解决方案):

private PendingIntent buildPendingIntentForNotification(String type) {
        Intent resultIntent = new Intent(this, MainActivity.class);
        //resultIntent.setAction(Intent.ACTION_VIEW);
        resultIntent.setAction(Intent.ACTION_MAIN);
        resultIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        resultIntent.putExtra(CommonUtils.NOTIFICATION_TYPE, type);
        PendingIntent resultPendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        return resultPendingIntent;
    }