仅出于测试目的,我允许通过URL下载和安装我的应用APK。一旦下载到手机上,便可以通过Android应用安装程序启动,该安装程序为用户提供了将其安装到其设备上然后运行它的选项。

考虑我们是否以上述方式下载并运行了该应用程序。我的应用程序中的主要/启动器 Activity 是登录页面(Activity A)。用户通过身份验证后,将被带到应用程序的主要区域,例如Activity B。因此,此任务的当前 Activity 堆栈为A > B

然后,我按手机上的主屏幕按钮,然后转到Android主屏幕。我通过菜单中的图标重新启动应用程序,然后转到Activity A,而不是Activity B。现在, Activity 堆栈为A > B > A,或者现在有两个单独的任务, Activity 堆栈分别为A > BA。重新启动应用程序时,我想要的是回到Activity B。在这种状态下按回去将带我回到Activity B

仅当我首先通过安装程序打开应用程序时才会发生这种不希望的行为,而如果我通过主屏幕/菜单打开应用程序则不会发生。

我研究了每种机制如何开始 Activity 。使用应用安装程序时,我们会看到以下日志:

INFO/ActivityManager(XXXX): Starting activity: Intent { dat=file:///mnt/sdcard/download/[my app].apk cmp=com.android.packageinstaller/.InstallAppProgress (has extras) }
INFO/ActivityManager(XXXX): Starting activity: Intent { act=android.intent.action.MAIN flg=0x10000000 cmp=[my package]/[Activity A] }

通过启动器/主屏幕:
INFO/ActivityManager(XXXX): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=[my package]/[Activity A] }

当使用安装程序启动时,我们看到它正在使用0x10000000标志,但是当使用启动程序启动时,我们看到它正在使用0x10200000。它还使用了意图类别。

docs中,我们看到的标志是:
public static final int FLAG_ACTIVITY_NEW_TASK
Constant Value: 268435456 (0x10000000)

public static final int FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
Constant Value: 2097152 (0x00200000)

标志FLAG_ACTIVITY_RESET_TASK_IF_NEEDED(从启动器启动应用程序时正在使用)似乎通常阻止创建新任务(如果已经存在),并将恢复上一次使用的 Activity 。这是期望的行为。为什么在这种情况下不起作用?有什么我可以确保我的应用程序始终使我返回上一个 Activity 的方法,无论它是通过应用程序安装程序/启动程序启动的吗?

如果我使用singleTask,无论何时我运行该应用程序,它总是会带我回到主要 Activity (Activity A)(这也不可取)。

这是我发现有人遇到类似问题(没有可接受的答案)的问题:App loses its ability to remember its stack when launched from another application

编辑:检查启动器 Activity 的FLAG_ACTIVITY_BROUGHT_TO_FRONT中的标志onCreate()(然后完成设置(如果已设置))似乎可以解决主要症状,但是显然潜在的问题仍然存在。是否有更完整的修复程序?

EDIT2:当您从Android Market下载/运行应用程序时,会出现相同的结果,因此上述某些详细信息可能不相关。

最佳答案

添加了anantyt提供的答案:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
        // Activity was brought to front and not created,
        // Thus finishing this will get us to the last viewed activity
        finish();
        return;
    }

    // Regular activity creation code...
}

09-10 04:13
查看更多