从Android应用安装程序和主屏幕启动应用程序时的活动堆栈排序问题

时间:2011-06-15 10:42:49

标签: android android-activity android-intent task flags

仅出于测试目的,我允许通过URL下载和安装我的应用APK。在手机上下载后,可以使用Android应用安装程序启动它,用户可以选择将其安装到自己的设备上然后再运行。

考虑我们是否以上述方式下载并运行应用程序。我的应用中的主/启动器活动是登录页面(Activity A)。一旦用户被认证,他们就被带到应用程序的主要区域,例如, Activity B。所以现在这个任务的当前活动堆栈是A > B

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

如果我首先通过安装程序打开应用程序,而不是通过主屏幕/菜单打开应用程序,则会发生此不良行为。

我研究了各机制如何开展活动。当我们使用app安装程序时,我们会看到以下日志:

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(从启动器启动应用程序时使用)似乎通常会阻止创建新任务(如果已存在),并将恢复上次使用的活动。这是期望的行为。为什么不能在这种情况下工作?有什么我可以做的,以确保我的应用程序将始终返回到最后一个活动,无论它是通过应用程序安装程序/启动器启动?

如果我使用singleTask,只要我运行应用程序(这也是不可取的),它总会让我回到主要活动(Activity A)。

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

编辑:检查我们的启动器活动的FLAG_ACTIVITY_BROUGHT_TO_FRONT中的标记onCreate()(如果已设置则检查完毕)似乎可以解决主要症状,但显然基本问题仍然存在。有更完整的解决方案吗?

EDIT2:从Android电子市场下载/运行应用时会出现相同的结果,因此上述某些细节可能不相关。

3 个答案:

答案 0 :(得分:30)

添加了antonyt提供的答案:

@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...
}

答案 1 :(得分:12)

我认为潜在的问题是启动器和安装程序之间使用的Intent不同。只要您获得不同的Intent标志,您将获得不同的启动行为。你可以使用启动模式,你可能会得到一致的结果,但从根本上说那些不同的意图会产生不同的结果。

您的修复(或this之类的内容)可能是您最好的选择。

答案 2 :(得分:0)

您的问题很可能源于App安装程序不使用LAUNCHER类别,启动器也是如此。

此错误已在其他地方记录:

App always starts fresh from root activity instead of resuming background state (Known Bug)