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

仅用于testing目的,我允许我的应用APK通过URL下载和安装。 一旦在手机上下载,就可以通过Android应用程序安装程序启动,该应用程序安装程序可以让用户select将其安装到设备上,然后运行。

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

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

这种不希望的行为只发生在我通过安装程序打开应用程序时,而不是通过主屏幕/菜单打开应用程序。

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

 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 。 它也在使用一个意图类别。

从文档我们看到的标志是:

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

如果我使用singleTask那么每当我运行应用程序(这也是不可取的)时,它总会把我带回到主要活动( Activity A )。

这里有一个问题,我发现有人遇到类似的问题(没有接受的答案): 应用程序失去了从另一个应用程序启动时记住它的堆栈的能力

编辑:检查我们的启动器活动(然后完成,如果设置)的onCreate()标志FLAG_ACTIVITY_BROUGHT_TO_FRONT似乎修复主要症状,但显然,潜在的问题仍然存在。 有没有更完整的解决scheme?

编辑2:从Android电子市场下载/运行应用程序时出现相同的结果,因此上面的某些细节可能不相关。

添加了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... } 

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

你的修复(或类似的东西)可能是你最好的select。

您的问题可能根植于App安装程序不像启动程序那样使用LAUNCHER类别。

这个错误已经在其他地方有logging

应用程序始终从根活动开始,而不是恢复后台状态(已知错误)