如何使用 Intent.FLAG_ACTIVITY_CLEAR_TOP 清除 Activity Stack?

Posted

技术标签:

【中文标题】如何使用 Intent.FLAG_ACTIVITY_CLEAR_TOP 清除 Activity Stack?【英文标题】:How do you use Intent.FLAG_ACTIVITY_CLEAR_TOP to clear the Activity Stack? 【发布时间】:2011-05-19 13:41:29 【问题描述】:

我已经阅读了几篇关于使用它的帖子,但一定遗漏了一些东西,因为它不适合我。我的活动 A 在清单中有 launchmode="singleTop" 。它使用launchmode="singleInstance" 启动活动B。活动 B 打开浏览器并接收并返回意图,这就是它是单实例的原因。我正在尝试覆盖返回按钮,以便将用户发送回活动 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,浏览器,B

我希望这段代码将堆栈更改为... 一种 ...因此,再次按下返回会将用户带回主屏幕。

相反,它似乎将堆栈更改为... A,B,浏览器,B,A ...就好像那些标志不存在一样。

我尝试在 startActivity 之后在活动 B 中调用 finish(),但随后返回按钮将我再次带回浏览器!

我错过了什么?

【问题讨论】:

【参考方案1】:

我已经开始了活动 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);
       

【讨论】:

这个解决方案是关闭所有中间活动;而且,重新启动 RootActivity。您可以在下面查看@Steel_Fedex 的解决方案。它的作用相同,但不会重新启动 RootActivity。 这是我的情况的最佳解决方案。我实际上想要根活动再次启动【参考方案2】:

@bitestar 有正确的解决方案,但还有一步:

它隐藏在文档中,但是您必须将 ActivitylaunchMode 更改为 standard 以外的任何内容。否则它将被销毁并重新创建,而不是重置到顶部。

【讨论】:

其实...Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP 会做到这一点。 以 Steel_fedex 的解决方案为例。 那么 Steel_fedex 的解决方案到底在哪里?!【参考方案3】:

为此,我使用FLAG_ACTIVITY_CLEAR_TOP 标志来启动Intent(没有FLAG_ACTIVITY_NEW_TASK

launchMode = "singleTask" 在已启动活动的清单中。

似乎它可以按我的需要工作 - 活动没有重新启动,所有其他活动都已关闭。

【讨论】:

我检查了,Bitster 的解决方案不起作用。虽然这个解决方案有效。 RootActivity 没有重新启动。 用词更明智。 Bitestar 解决方案确实有效! singleTask 为我工作,所以 Activity 不会重新创建,并在 onNewIntent 中处理事件。【参考方案4】:

虽然这个问题已经有了足够的答案,但我想有人会想知道为什么这个标志会以这种特殊的方式工作,这就是我在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 作为您的标志。然后它会按照你想要的方式工作。

【讨论】:

【参考方案5】:

我使用三个标志来解决问题:

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
                Intent.FLAG_ACTIVITY_CLEAR_TASK | 
                Intent.FLAG_ACTIVITY_NEW_TASK);

【讨论】:

【参考方案6】:

在清单文件中添加 android:noHistory="true"。

<manifest >
        <activity
            android:name="UI"
            android:noHistory="true"/>

</manifest>

【讨论】:

第一次看到这个标志,但它适用于我的情况,谢谢【参考方案7】:

我在开始新意图后打电话给activity_name.this.finish(),它对我有用。

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

但这对我不起作用...我不建议使用此解决方案,但如果设置标志对您不起作用,那么您可以尝试这个..但我仍然建议不要使用它

【讨论】:

【参考方案8】:

我知道已经有一个公认的答案,但我不明白它对 OP 的作用,因为我认为 FLAG_ACTIVITY_CLEAR_TOP 在他的特定情况下没有意义。该标志仅与同一任务中的活动相关。根据他的描述,每个活动都有自己的任务:A、B 和浏览器。

可能让他失望的是A是singleTop,而它应该是singleTask。如果 A 是 singleTop,而 B 启动 A,那么会创建一个新的 A,因为 A 不在 B 的任务中。来自 singleTop 的文档:

“如果 当前任务的顶部已经存在 Activity 的实例,则系统将 Intent 路由到该实例...”

由于B启动A,当前任务是B的任务,它是针对singleInstance的,因此不能包含A。使用singleTask在那里达到预期的结果,因为系统会找到具有A的任务并将该任务带到前景。

最后,在 B 启动 A 之后,用户从 A 按下返回,OP 不想看到 B 或浏览器。为此,在 B 中调用 finish() 是正确的;同样,FLAG_ACTIVITY_CLEAR_TOP 不会删除 A 任务中的其他活动,因为他的其他活动都在不同的任务中。但是,他缺少的部分是 B 在触发浏览器的意图时也应该使用 FLAG_ACTIVITY_NO_HISTORY。 注意:如果浏览器在启动 OP 的应用程序之前就已经在运行,那么当从 A 按下返回时,您当然会看到浏览器。所以要真正测试这一点,请务必退出启动应用程序之前的浏览器。

【讨论】:

【参考方案9】:

FLAG_ACTIVITY_NEW_TASK 是此处启动新任务的问题。只需将其删除即可完成。

我建议您在使用它们之前阅读每个 Flag 的作用

阅读this & Intent Flags here

【讨论】:

我确实读过国旗,这听起来像是我需要的。无论如何,删除 FLAG_ACTIVITY_NEW_TASK 对结果没有影响。它仍然是一个无休止的后退按钮循环...... A->B,回到A,回到B,回到A...... 你确定为什么要使用 B 作为 singleInstance 吗?A “singleInstance”活动的行为就像 FLAG_ACTIVITY_NEW_TASK 是在意图中一样。检查developer.android.com/guide/topics/fundamentals.html B 需要接收浏览器回调的意图。我尝试将启动模式更改为 singleTask,这仍然有效,但仍然会出现返回按钮循环。 我认为它不起作用,因为您在那里使用了 FLAG_ACTIVITY_NEW_TASK。最好只使用 FLAG_ACTIVITY_CLEAR_TOP 并避免使用 singleTask 和 singleInstance 我认为这应该是一个可行的解决方案,如果您添加 Intent.FLAG_ACTIVITY_SINGLE_TOP 以防止重新创建【参考方案10】:

最初我也无法让 FLAG_ACTIVITY_CLEAR_TOP 工作。最终我通过使用它的值(0x04000000)让它工作。所以看起来有一个 Eclipse/编译器问题。但不幸的是,幸存的活动被重新启动,这不是我想要的。所以看起来没有简单的解决方案。

【讨论】:

以上是关于如何使用 Intent.FLAG_ACTIVITY_CLEAR_TOP 清除 Activity Stack?的主要内容,如果未能解决你的问题,请参考以下文章

如果加入条件,我该如何解决。如果使用字符串连接,我如何使用

如何使用本机反应创建登录以及如何验证会话

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?

如何使用laravel保存所有行数据每个行名或相等

如何使用 Math.Net 连接矩阵。如何使用 Math.Net 调用特定的行或列?