Android:清除返回栈

362

在Android中,我有一些活动,假设它们是A,B,C。

在A中,我使用以下代码打开B:

Intent intent = new Intent(this, B.class);
startActivity(intent);
在B中,我使用以下代码来打开C:
Intent intent = new Intent(this, C.class);
startActivity(intent);

当用户在C中点击按钮时,我希望返回A并清除后退栈(关闭B和C)。因此,当用户使用后退按钮时,B和C将不会出现。我一直在尝试以下操作:

Intent intent = new Intent(this, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(intent);

但是当我回到活动A时,如果我使用后退按钮,B和C仍然会出现。我该如何避免这种情况?

39个回答

480
尝试按照FLAG_ACTIVITY_CLEAR_TOP的文档所述,添加FLAG_ACTIVITY_NEW_TASK

如果与FLAG_ACTIVITY_NEW_TASK一起使用,此启动模式也可以产生良好的效果:如果用于启动任务的根活动,则会将该任务的任何当前运行实例带到前台,然后将其清除为其根状态。这在从通知管理器启动活动时特别有用。

因此,启动A的代码如下:

Intent intent = new Intent(this, A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);
CurrentActivity.this.finish(); // if the activity running has it's own context


// view.getContext().finish() for fragments etc.

33
谢谢但我已经尝试过了。仍然是当我点完 C 后,点击返回按钮时会再次显示 C。我可能错过了什么吗? - Martin
5
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);这段代码的意思是给一个Intent对象添加标志,其中包括清除任务栈顶部的Activity并创建新的任务。 - dzeikei
8
调用finish()方法可以实现我想要的效果,但对我来说并不起作用。 - 2cupsOfTech
11
我也遇到了同样的问题,解决方法是在启动新的活动后调用finish()。 - Arno van Lieshout
24
我也添加了一个更加清晰的意图 Intent intent = new Intent(SingUpActivity.this, LoginActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); - Samir
显示剩余13条评论

184
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

13
对于CLEAR_TOP标志,我表示最高的敬意-这种组合是唯一能够完全清空整个堆栈并使新的活动成为应用程序中唯一的活动。谢谢! - Aviel Gross
9
这个和被接受的答案有何不同? - Yuri Heupa
8
感谢您的信任,与已接受答案不同的是,使用此标记,我们无需调用activity.finish。 - Pablo Cegarra
1
FLAG_ACTIVITY_CLEAR_TASK 与 NEW_TASK 完美地配合运作。 - Shamsul Arefin
1
这应该是被接受的答案。非常感谢。 - Danish Ansari
显示剩余4条评论

82

那关于在清单文件(manifests file)中添加相关活动(related activity)怎么办呢:

android:noHistory="true"

添加到B和C的活动定义中?它们不会被添加到后退栈。不确定这是否是您想要的。


3
使用时请非常小心——如果您正在使用与Facebook登录或任何类似功能相关的功能。 - Skynet
3
@ Skynet 为什么?这样做有哪些问题与之相关? - Alfie Woodland
13
当您从nohistory为true的页面将控制权传递给FB进行登录时,FB应用程序不知道在用户登录后要登陆到哪里,在我的情况下,它返回到手机主屏幕,我差点失去了工作! - Skynet
这并不允许将一个活动添加到后退栈... 这不是正确的解决方案。 - Tarun Deep Attri
确切地说,这正是我在寻找的。 - Masum
只有这个答案对我有用。因为突然间返回按钮跳转到了错误的活动。我不知道怎么回事。但是这个答案至少让我确定没有任何活动发生在堆栈中。 - Exutic

65
很长一段时间以来,这件事一直困扰着我。最终,我通过以下方法解决了它:
在代码片段中,使用:
Intent intent = new Intent(view.getContext(), A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);

在Activity中,与Fragment相比使用(add one more intent flag Intent.FLAG_ACTIVITY_CLEAR_TASK):

Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

1
如果您正在使用AndroidAnnotations,则必须添加:Intent.FLAG_ACTIVITY_CLEAR_TASK。 - yosafatade
Activity解决方案对我来说很好用。虽然我认为使用API 16,Daniel Schuler的解决方案更简单。 - PhilippS
谢谢yosafatade,那就是我所缺少的! - Marty Miller

35

如果您已经在API 16上,这是一个非常有用且易于使用的解决方案。对我很有效! - PhilippS
4
提醒:这仅适用于具有相同任务亲和性名称的活动。 - Ryhan
这只会在历史记录中有一个活动时起作用。 - arsent

31
  1. 在你的manifest文件中的Activity A元素中添加android:launchMode="singleTop"
  2. 当启动Activity A时,使用intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

这意味着当启动Activity A时,所有在它上面的任务都将被清除,以便A位于顶部。创建一个新的返回堆栈,并且使用singleTop确保您只启动A一次(因为由于..._CLEAR_TOP,A现在处于顶部)。


3
好的,我会尽力进行翻译。以下是需要翻译的内容:是的,这就是我现在正在使用的,但这并没有起作用。当我按返回按钮时,仍然会出现“C”。 - Martin
奇怪,我在一个项目中使用这个功能,它正常工作...按返回键会把我带回到主屏幕。也许还有其他问题。你能发一下你的清单文件吗? - Joseph Earl
我重新启动了模拟器,现在它看起来像你说的那样正常工作了。非常感谢你的帮助! - Martin
singleTop 应该与清除堆栈无关。 - stdout

19
尝试使用。
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

而不是

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

这个可以工作。我的假设是使用 setFlags 将替换所有默认设置的标志,但事实并非如此。 - William

18
如果您的应用程序最低sdk版本为16,则可以使用finishAffinity() 结束这个活动以及当前任务中所有与它具有相同关联性的立即下面的活动。
这对我很有帮助。在顶部支付屏幕中删除所有后退堆栈活动。
 @Override
public void onBackPressed() {
         finishAffinity();
        startActivity(new Intent(PaymentDoneActivity.this,Home.class));
    } 

http://developer.android.com/reference/android/app/Activity.html#finishAffinity%28%29


10
Use finishAffinity() to clear all backstack with existing one.

Suppose, Activities A, B and C are in stack, and finishAffinity(); is called in Activity C, 

    - Activity B will be finished / removing from stack.
    - Activity A will be finished / removing from stack.
    - Activity C will finished / removing from stack.

9
根据 WakkaRemoving an activity from the history stack 的说法,将 <activity> 标签添加到 AndroidManifest.xml 文件中并设置 android:noHistory="true" 属性。
    <activity android:name=".MyActivity"
        android:noHistory="true">
    </activity>

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