Android: 使用singleTop或SingleTask模式恢复一个Activity

6
我已经花费了很长时间寻找解决方案,但是Android文档不够清晰,网上的解决方案也不能完全解决我的问题。
我正在开发一个游戏,其中主Activity(游戏进行的地方)可以调用另一个简单的Activity,然后返回。它应该像这样工作:
1. 如果用户点击Home按钮,然后返回到游戏,Activity必须在不通过onDestroy的情况下停止并恢复(否则将丢失游戏状态) 2. 当主Activity调用其他Activity然后返回到游戏时,同样的功能。 3. 当用户按退出按钮时,游戏必须完全退出。
对于前两个问题,我尝试使用“android:launchMode =”singleTask“”或“android:launchMode =”singleTop“”,以确保创建和调用一个主Activity,但不幸的是,第一个只适用于第一个问题,第二个只适用于第二个问题,而不是同时适用。
我认为问题在于:使用singleTop时,当第二个Activity调用它时,主Activity实际上并没有在堆栈的顶部(换句话说,我不明白何时会出现这样的情况,即调用已经在堆栈的顶部的Activity!)。相反,singleTask确保Activity在其堆栈中是唯一的,但是用户点击Home按钮并返回应用程序后,将调用其他Task,对吗?
无论如何,这是一个明智的解决方案,还是我应该在onStop / onPause中保存游戏状态,然后在onResume中恢复它?
对于第三个问题,我尝试将“android:noHistory =”true“”添加到每个Activity中,然后当用户单击退出按钮时,调用一个什么都不做的新Activity,但在onCreate上仅使用finish()方法。此Activity使用“intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);”进行调用,并且其launchMode为“singleInstance”,但它不起作用,它总是返回主Activity。
1个回答

3
您绝对不想搞乱launchMode,这不是解决问题的方式,只会导致更多问题。
在Android中,系统随时可能(尤其是当您的应用在后台运行时)杀死您的进程。因此,您需要在onPause()中保存游戏状态,因为这是您确保拥有的唯一机会。
无论如何,如果您在onPause()中保存了游戏,则标准行为将覆盖您的前两个点。
对于第三个点,有几个选择:
  1. 您可以使用startActivityForResult()启动所有活动,参见我的答案here
  2. 当您想要“退出”时,只需返回到您的根活动(启动您的应用程序的活动),并告诉它您想要退出。
就像这样:
Intent intent = new Intent(this, MyRootActivity.class); // this is the starting activity for your application
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // tells Android to finish all other activities in the stack
intent.addExtra("exit", "true"); // this tells your root activity that you want to exit
startActivity(intent);

现在,在您的MyRootActivity中,您想将此代码添加到onCreate()中:
Intent intent = getIntent();
if (intent.hasExtra("exit")) {
    // User wants to exit
    finish();
}

感谢您的回答。对于前两个问题,我使用了android:launchMode="singleTask"并删除了android:noHistory="true"(我认为这是真正的问题)。在onPause()中保存状态可能是一个选项,但是如何保存Activity的UI外观呢? 关于第三个问题...这正是我使用的解决方案,但是由于其他任务中有主Activity,所以它没有起作用。我解决了在根Activity上调用finish(),然后在主Activity的onResume()中检查是否设置了“exit”标志,在这种情况下,我立即调用finish()。 - mordicchio
你不需要使用 launchMode="singleTask"。标准的启动模式可以实现你想要的功能。如果不能,那么你可能在做其他错误的事情。整个应用程序应该在一个任务中运行,而不是多个任务中。没有理由这样做。 - David Wasser
1
我同意,但这不是我的错,问题在于Google的疯狂选择!我希望主Activity始终只有一个(除非极少数低内存情况下需要销毁),并且该Activity不能位于堆栈顶部。因此,经典的launchMode会创建多个Activity实例,而singleTop仅在Activity位于堆栈顶部时恢复该Activity,但如果我从另一个Activity中调用它,我不明白它如何能够位于堆栈顶部! - mordicchio
如果你正在得到你的主活动的多个实例,那么你做错了什么。解释一下你在哪里得到了多个实例以及在这些情况下如何启动活动。 - David Wasser
1
你应该在onSaveInstanceState中保存状态,而不是在onPause中保存。 - Greg Ennis

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