应用程序总是从根活动重新启动,而不是恢复后台状态(已知错误)

50

我遇到了这些链接中提到的问题:

http://code.google.com/p/android/issues/detail?id=2373

http://groups.google.com/group/android-developers/browse_thread/thread/77aedf6c7daea2ae/da073056831fd8f3?#da073056831fd8f3

http://groups.google.com/group/android-developers/browse_thread/thread/2d88391190be3303?tvc=2

我有一个简单的根活动,具有LAUNCHER和MAIN意图,没有其他内容。我启动另一个活动,它在清单中没有任何标志或其他额外内容

我启动应用程序(根活动),然后从那里启动第二个活动。按下Home键后,任务进入后台。再次启动应用程序(从Launcher或从按住Home键的最近应用程序),它会在现有堆栈的顶部启动根活动的新实例。

如果我按下返回按钮,新的“根”活动将关闭,旧的第二个活动将可见,这意味着它在同一任务中启动了根活动,而不是将任务带到前台。

为了解决这个问题,我将根活动的启动模式设置为singleTask。现在,当我按下Home并再次启动应用程序时,它会清除旧根任务上面的活动,并将旧根任务带到前台,而不仅仅是将整个旧任务与2号活动置于顶部。请注意,旧的根任务仍保留其应用程序状态,这意味着它不是一个新实例,但较高级别的活动已被终止。

这甚至发生在从市场下载的其他应用程序中。手动安装方法对我没有影响,它仍然以同样的方式启动。


Kurian,我也遇到了同样的问题。有什么解决方法吗?先谢过了。 - Vit Khudenko
1
在从Eclipse部署应用程序后,只需不断按返回按钮并完全退出应用程序。然后从手机上再次启动它。 - Monstieur
可能是[从Android应用程序安装程序和主屏幕启动应用程序时的Activity堆栈排序问题]的重复问题(https://dev59.com/ZGw15IYBdhLWcg3w3ffN)。 - blahdiblah
4个回答

25

这是因为启动应用程序所使用的意图不同。Eclipse使用没有操作和类别的Intent来启动应用程序。而启动器使用具有android.intent.action.MAIN操作和android.intent.category.LAUNCHER类别的Intent来启动应用程序。安装程序使用具有android.intent.action.MAIN操作和没有类别的Intent来启动应用程序。

提交错误报告的人可能应该把它表述为对Eclipse插件的增强请求,因为他们显然希望Eclipse能够假装成启动器,并使用与启动器相同的Intent来启动应用程序。


2
然而,问题在于即使直接从手机上启动应用程序,这个问题仍然存在... - Monstieur
1
是的,Kurian是正确的 - 这不仅仅是Eclipse插件问题。在OTA升级时,设备上也会发生同样的情况。这是我遇到的最奇怪的Android问题。简直不敢相信它仍然是一个一年前创建的新问题!!! - Vit Khudenko
1
到目前为止,似乎这个问题还没有得到解决。嗯...不知道那边的人真正在做什么? - source.rar
嗯,我的测试表明Lance是正确的。如果我从Eclipse运行它,我的startupActivity.onCreate每次恢复时都会被执行。但是,如果我从设备启动,当恢复时我不会得到onCreate的执行...在三星S2上运行2.3.3。 - Ted
然而,第二个启动的Activity在resume时不会显示出来,结果又出现了该死的StartupActivity... 嗯 - Ted
显示剩余2条评论

6

以下是解决方案:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0 & getIntent().getExtras() == null) {
        finish();
        return;
    }

 Your code....
}

编辑:我在使用新的意图和通知时遇到了问题。之前的解决方案无法处理通知和意图...


2
只需在启动器活动的onCreate方法中添加以下内容,如下所示:
      @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);
    if (!isTaskRoot()) {
        finish();
        return;
    }
    // other function
    }

0

针对Xamarin.Android的类似解决方案:

if (!IsTaskRoot)
            {
                string action = this.Intent.Action;
                if (this.Intent.HasCategory(Intent.CategoryLauncher) && !string.IsNullOrEmpty(this.Intent.Action) && action == Intent.ActionMain)
                {
                    Finish();
                    return;
                }
            }

@HimanshuDwivedi 这是针对一个非常老的错误,你不再需要它了。 - CDrosos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接