应用程序重新启动而不是恢复?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (16)

希望有人能帮我弄清楚,如果不是解决方案,至少可以解释一种行为。

问题:

在某些设备上,按下启动器图标会导致当前任务被恢复,而在其他设备上导致初始启动意图被触发(有效重新启动应用程序)。为什么会发生?

细节:

当你按下“启动器图标”时,应用程序会正常启动 - 也就是说,我认为,一个意图是以你的名字Activity与动作android.intent.action.MAIN和类别一起启动的android.intent.category.LAUNCHER。但是,这并不总是如此:

在大多数设备上,如果您在应用程序已经运行之后按下启动器图标,则该进程中当前正在运行的Activity将恢复(不是初始状态Activity)。它的恢复方式与您从OS菜单中的“近期任务”中选择它相同。这是我想要的所有设备上的行为。

但是,在选定的其他设备上会发生不同的行为

  • 在Motorola Xoom上,当您按下启动器图标时,应用程序将始终启动初始启动,Activity无论当前运行的是什么。我假设启动器图标总是启动“LAUNCHER”意图。
  • 在Samsung Tab 2上,当您按下启动器图标时,如果您刚刚安装了应用程序,它将始终启动初始Activity(与Xoom相同) - 但是,在安装后重新启动设备后,启动器图标将会改为恢复应用程序。我假设这些设备在设备启动时将“已安装的应用程序”添加到查找表中,允许启动器图标正确恢复正在运行的任务?

我读过许多回答听起来类似我的问题,但简单地添加android:alwaysRetainTaskState="true"或使用launchMode="singleTop"Activity不是答案。

提问于
用户回答回答于

这个问题在2016年仍然相关。今天,QA测试人员报告了一个应用程序重新启动,而不是 Android M 的股票启动器恢复。

实际上,系统将已启动的活动添加到当前的任务堆栈中,但对用户来说似乎发生了重新启动并且他们已经失去了工作。序列是:

  1. 从Play商店下载(或sideload apk)
  2. 从Play商店对话框启动应用程序:活动A出现[任务堆栈:A]
  3. 导航到活动B [任务堆栈:A - > B]
  4. 按'首页'按钮
  5. 从应用程序抽屉启动应用程序:显示活动A![任务堆栈:A - > B - > A](用户可以按'返回'按钮从这里进入活动'B')

注意:通过ADB部署的调试APK不会显示此问题,只能在从Play商店下载的APK或侧面加载的APK中显示。在后一种情况下,步骤5中的启动意图包含标志Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT,但不包含在调试案例中。一旦应用程序从启动器冷启动,问题就会消失。我的怀疑是任务种植了一个格式错误(更准确,非标准)的Intent,它会阻止正确的启动行为,直到完全清除任务。

我尝试了各种活动启动模式,但这些设置与用户期望的标准行为偏离太多:在活动B处恢复任务。请参阅页面底部的任务和返回堆栈指南中的预期行为的以下定义在“启动任务”下:

这种意图过滤器会使活动的图标和标签显示在应用程序启动器中,为用户提供一种启动活动并返回其启动后任何时间创建的任务的方式。

将以下内容插入到我的根活动(A)的'onCreate'方法中,以便在用户打开应用程序时适当恢复。

                    /**
     * Ensure the application resumes whatever task the user was performing the last time
     * they opened the app from the launcher. It would be preferable to configure this
     * behavior in  AndroidMananifest.xml activity settings, but those settings cause drastic
     * undesirable changes to the way the app opens: singleTask closes ALL other activities
     * in the task every time and alwaysRetainTaskState doesn't cover this case, incredibly.
     *
     * The problem happens when the user first installs and opens the app from
     * the play store or sideloaded apk (not via ADB). On this first run, if the user opens
     * activity B from activity A, presses 'home' and then navigates back to the app via the
     * launcher, they'd expect to see activity B. Instead they're shown activity A.
     *
     * The best solution is to close this activity if it isn't the task root.
     *
     */

    if (!isTaskRoot()) {
        finish();
        return;
    }

用户回答回答于

这是三星设备以及使用自定义启动器/皮肤的其他制造商的相对常见问题。我还没有看到这个问题发生在股票Android启动器上。

基本上,应用程序实际上并未完全重新启动,但启动Activity正在启动,并在启动器恢复应用程序时将其添加到Activity堆栈的顶部。当您恢复应用程序并显示启动活动时,您可以通过单击后退按钮来确认这种情况。然后,您应该将其带到您希望在恢复应用程序时显示的活动。

我选择实施以解决此问题的解决方法是在启动初始活动的意图中检查Intent.CATEGORY_LAUNCHER类别和Intent.ACTION_MAIN操作。如果这两个标记存在,并且Activity不在任务的根部(意味着该应用程序已经在运行),那么我将在最初的Activity上调用finish()。这个确切的解决方案可能不适合你,但类似的应该。

以下是我在初始/启动Activity的onCreate()中所做的工作:

    if (!isTaskRoot()
            && getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
            && getIntent().getAction() != null
            && getIntent().getAction().equals(Intent.ACTION_MAIN)) {

        finish();
        return;
    }

扫码关注云+社区