我已经阅读了几篇关于使用它的帖子,但一定遗漏了一些东西,因为它对我不起作用。我的活动 A 在清单中有 launchmode="singleTop" 。它以 launchmode="singleInstance" 启动活动 B。 Activity B 打开浏览器并接收并返回,这就是它是 singleInstance 的原因。我正在尝试覆盖后退按钮,以便将用户发送回活动 A,然后可以按返回离开活动,而不是再次返回活动 B。
// activity B
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR
&& keyCode == KeyEvent.KEYCODE_BACK
&& event.getRepeatCount() == 0) onBackPressed();
return super.onKeyDown(keyCode, event);
}
@Override
public void onBackPressed() {
startActivity(new Intent(this, UI.class)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
return;
}
从浏览器返回后,栈是... A,B,Browser,B
我希望此代码将堆栈更改为... A ... 以便再次按下返回将用户带回主屏幕。
相反,它似乎将堆栈更改为... A,B,Browser,B,A ...就好像那些标志不存在一样。
我尝试在 startActivity 之后在活动 B 中调用 finish(),但是后退按钮再次将我带回浏览器!
我错过了什么?
我已经开始了活动 A->B->C->D。当在活动 DI 上按下后退按钮时,我想转到活动 A。由于 A 是我的起点,因此已经在堆栈中,A 顶部的所有活动都被清除,你不能从 A 返回任何其他活动.
这实际上适用于我的代码:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
Intent a = new Intent(this,A.class);
a.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(a);
return true;
}
return super.onKeyDown(keyCode, event);
}
@bitestar 有正确的解决方案,但还有一步:
它隐藏在文档中,但是您必须将 Activity
的 launchMode
更改为 standard
以外的任何内容。否则它将被销毁并重新创建,而不是被重置到顶部。
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP
会这样做。
为此,我使用 FLAG_ACTIVITY_CLEAR_TOP
标志来启动 Intent
(不带 FLAG_ACTIVITY_NEW_TASK
)
和 launchMode = "singleTask"
在已启动活动的清单中。
似乎它可以按我的需要工作 - 活动不会重新启动并且所有其他活动都已关闭。
虽然这个问题已经有了足够的答案,但我想有人会想知道为什么这个标志会以这种特殊的方式工作,这就是我在 Android documentation 中发现的
上面示例中当前运行的活动 B 实例将在其 onNewIntent() 方法中接收您在此处启动的新意图,或者自身完成并使用新意图重新启动。如果它已声明其启动模式为“多重”(默认)并且您没有在同一意图中设置 FLAG_ACTIVITY_SINGLE_TOP,那么它将完成并重新创建;对于所有其他启动模式,或者如果设置了 FLAG_ACTIVITY_SINGLE_TOP,则此 Intent 将被传递到当前实例的 onNewIntent()。
所以,要么,
1。将活动 A 的 launchMode
更改为标准的其他内容(即 singleTask
或其他内容)。那么您的标志 FLAG_ACTIVITY_CLEAR_TOP
将不会重新启动您的 Activity A。
或者,
2。使用 Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP
作为您的标志。然后它会按照你想要的方式工作。
我使用三个标志来解决问题:
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
Intent.FLAG_ACTIVITY_CLEAR_TASK |
Intent.FLAG_ACTIVITY_NEW_TASK);
在清单文件中添加 android:noHistory="true" 。
<manifest >
<activity
android:name="UI"
android:noHistory="true"/>
</manifest>
我在开始新的意图后打电话给 activity_name.this.finish()
,它对我有用。
I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"
但这对我不起作用...我不建议使用此解决方案,但如果设置标志对您不起作用,那么您可以尝试这个..但我仍然建议不要使用它
我知道已经有一个公认的答案,但我看不出它对 OP 的作用,因为我认为 FLAG_ACTIVITY_CLEAR_TOP 在他的特定情况下没有意义。该标志仅与同一任务中的活动相关。根据他的描述,每个活动都在自己的任务中:A、B 和浏览器。
可能让他失望的是A是singleTop,而它应该是singleTask。如果 A 是 singleTop,而 B 启动 A,那么会创建一个新的 A,因为 A 不在 B 的任务中。从 singleTop 的文档中:
“如果活动的实例已经存在于当前任务的顶部,系统会将意图路由到该实例......”
由于 B 启动 A,当前任务是 B 的任务,它是针对单个实例的,因此不能包含 A。使用 singleTask 在那里实现所需的结果,因为这样系统会找到具有 A 的任务并将该任务带到前台。
最后,在 B 启动 A 并且用户从 A 按下回之后,OP 不想看到 B 或浏览器。为此,在 B 中调用 finish() 是正确的;同样,FLAG_ACTIVITY_CLEAR_TOP 不会删除 A 任务中的其他活动,因为他的其他活动都在不同的任务中。不过,他缺少的部分是 B 在触发浏览器的意图时也应该使用 FLAG_ACTIVITY_NO_HISTORY。注意:如果浏览器在启动 OP 应用程序之前已经在运行,那么当从 A 按下返回时,您当然会看到浏览器。因此,要真正测试这一点,请务必在启动应用程序之前退出浏览器。
FLAG_ACTIVITY_NEW_TASK 是这里启动新任务的问题。只需将其删除即可。
好吧,我建议您在使用它们之前阅读每个 Flag 的作用
Intent.FLAG_ACTIVITY_SINGLE_TOP
以防止重新创建
最初我也有问题让 FLAG_ACTIVITY_CLEAR_TOP 工作。最终我通过使用它的值(0x04000000)让它工作。所以看起来有一个 Eclipse/编译器问题。但不幸的是,幸存的活动被重新启动,这不是我想要的。所以看起来没有简单的解决方案。