Android:清除后盖


330

在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仍会出现。如何避免这种情况?

Answers:


438

尝试FLAG_ACTIVITY_NEW_TASK按照文档中所述添加FLAG_ACTIVITY_CLEAR_TOP

此启动模式还可以与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.

28
谢谢,但是我已经尝试过了。仍然当我点击后退按钮后,它再次显示C。我会缺少什么?
马丁

4
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
dzeikei 2012年

8
不适用于我,但是在源活动上调用finish()
可以满足

10
我有一个同样的问题,那就是它不起作用。对我来说解决的是在开始新活动后调用finish()
Arno 2014年

20
我还添加了一个更清晰的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); 完();
山姆

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

8
CLEAR_TOP标志而言,这种组合是唯一可以完全清除整个堆栈并使新活动成为应用程序中唯一标志的组合。谢谢!
艾菲尔·格罗斯

8
这个和接受的答案有什么区别?
Yuri Heupa 2015年

7
谢谢,与可接受答案的不同之处在于,使用此标志,我们不需要调用activity.finish
Pablo Cegarra

1
FLAG_ACTIVITY_CLEAR_TASK完全与NEW_TASK一起工作
沙姆斯Arefin Sajib

1
这应该是公认的答案。非常感谢你。
MD Danish Ansari '18

77

如何为相关活动添加清单文件:

android:noHistory="true"

B和C的活动定义?它们不会被添加到堆栈中。不知道那是不是你想要的。


3
使用此功能时请务必小心-如果您要使用FB或其他类似功能登录
-Skynet

2
@天网为什么?这样做有什么问题?
Alfie Woodland'3

8
当您将控制权从没有历史记录的页面传递给FB进行登录时,FB应用程序在用户登录后现在无法登录,在我的情况下,该应用程序返回了电话主屏幕,我差点丢了工作!
天网

这不会使活动增加到堆栈中。...这不是正确的解决方案。
塔伦(Tarun)2016年

我确实在找
Masum

63

这困扰了我很长时间。最后我通过执行以下操作解决了这个问题:

分段使用:

Intent intent = new Intent(view.getContext(), A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);

在Activity中,使用(Intent.FLAG_ACTIVITY_CLEAR_TASK与片段相比,再添加一个intent标志):

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
如果您使用的是androidannotation,则必须添加:Intent.FLAG_ACTIVITY_CLEAR_TASK
yosafatade 2014年

活动甜菜碱对我来说很好。尽管我认为使用API​​ 16,但Daniel Schuler的解决方案更容易。
PhilippS 2014年

谢谢yosafatade,那是我所缺少的!
马蒂·米勒

30
  1. 添加android:launchMode="singleTop"到活动元素的清单发生的活性
  2. 然后使用intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)启动活动A时

这意味着启动活动A时,将清除活动A之上的所有任务,从而使活动A处于顶部。创建一个新的后向堆栈,其根为A,并且using singleTop确保您仅启动一次A(因为由于,A现在位于顶部..._CLEAR_TOP)。


3
是。这就是我现在正在使用的功能,但是没有做到。当我按下后退按钮时,仍然显示C。
马丁,

奇怪的是,我在项目中使用了它,并且效果很好...按下后回到我的主屏幕。也许还有其他事情发生。你可以张贴清单吗?
约瑟夫·厄尔

我重新启动了模拟器,现在好像您说的那样,它正在工作。非常感谢你的帮助!
马丁,

singleTop应该与清除堆栈无关。
stdout

29

从API 16(Jelly Bean)开始,您可以调用finishAffinity()

现在,您还可以ActivityCompat.finishAffinity(Activity activity)使用兼容性库进行调用。

确保将清单中的taskAffinity设置为该活动组唯一的程序包名称。

请参阅更多信息:http :
//developer.android.com/reference/android/support/v4/app/ActivityCompat.html#finishAffinity%28android.app.Activity%29


如果您已经使用API​​ 16,那将是非常实用且简便的解决方案,为我工作!
PhilippS 2014年

3
提醒:这仅适用于共享同一任务的活动亲和力名称
Ryan

仅当您在历史记录中只有一项活动时,此功能才有效。
arsent


11

如果您的应用程序的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



8

为了将来的研究,请尝试以下代码。

Intent intent = new Intent(context, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();

这些标志终于对我有用。我所做的是,我使用这些标志和一个布尔额外的EXIT = true进行了相同的活动。在onCreate()中,我检查了EXIT的启动参数,如果将其设置为true,则称为finish()。关闭自己的应用程序很麻烦。
珍妮·奥克萨南

8

使用finishAffinity(); 在任务C中启动任务A来清除堆栈活动。


只有这个答案对我有用。不需要Intent.FLAG_ACTIVITY_CLEAR_TOP和Intent.FLAG_ACTIVITY_NEW_TASK
nuttynibbles

7

使用此代码启动新的活动,然后关闭或销毁所有其他活动堆栈或后退堆栈。

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

5
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.

5

我找到了一个有趣的解决方案,可能会有所帮助。我用我的onBackPressed()方法做到了。

finishAffinity();
finish();

FinishAffinity删除现有活动与其堆栈的连接。然后完成可帮助您退出该活动。最终将退出应用程序。


4

我发现这里的答案有些误导,因为原始问题中的代码对我来说似乎很好用?

以A为根活动,仅使用FLAG_ACTIVITY_CLEAR_TOP从B或C开始将B和C从后堆栈中删除。


4

在kotlin中,它几乎与Java相同。仅| 符号由文本代替。因此,它写为-

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)

3

我尝试了所有解决方案,但没有一个单独为我工作。我的解决方案是:

声明Activity ASingleTop通过[android:launchMode="singleTop"]在Android清单。

现在,A从任何地方启动时添加以下标志。它将清除堆栈。

Intent in = new Intent(mContext, A.class);
in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK );
startActivity(in);
finish();

2

Intent.FLAG_ACTIVITY_CLEAR_TOP在这种情况下将不起作用。请用(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)

有关更多详细信息,请查阅文档。


2

像你需要开始这听起来我Activity CActivity B使用startActivityForResult()。当你点击一个按钮Activity C,呼叫setResult(RESULT_OK)finish()因此Activity C结束。在中Activity B,您还可以onActivityResult()通过调用finish()自身来获得响应,然后将您带回Activity A


7
是的,但是如果A和C之间有42个活动,这将非常乏味。标志FLAG_ACTIVITY_CLEAR_TOP应该直接执行OP想要的操作。
Guillaume Brunerie

这将不是实现OP所需的最佳方法,正如@Guillaume所说,在根与栈顶之间的所有活动中都需要代码。
Jake Basile

适当注意。这些是我显然需要了解的标志。
Maximus

1

logout.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); logout.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);


1

您可以使用此示例Activity AActivity C

Intent loout = new Intent(context, LoginActivity.class); loout.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); context.startActivity(loout);


1

对我来说,Intent.FLAG_ACTIVITY_CLEAR_TASK解决了这个问题

Intent i = new Intent(SettingsActivity.this, StartPage.class);
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP  | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);
finish();

1

先进的可重复使用的Kotlin:

您可以使用setter方法直接设置标志。在Kotlin中,or是按位Java或Java 的替代品|

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

如果多次使用,请创建一个Intent扩展函数

fun Intent.clearStack() {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

然后,您可以在启动意图之前直接调用此函数

intent.clearStack()

如果需要在其他情况下添加其他标志的选项,请向扩展功能添加可选参数。

fun Intent.clearStack(additionalFlags: Int = 0) {
    flags = additionalFlags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

0

除了FLAG_ACTIVITY_CLEAR_TOP,您也可以尝试添加Intent.FLAG_ACTIVITY_SINGLE_TOP

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);


那只会影响堆栈顶部的活动,而不影响堆栈的根。
Jake Basile

0

给定的代码可以正常工作。我已经在“应用程序生命周期”示例中进行了尝试。

在使用标志FLAG_ACTIVITY_CLEAR_TOP开始活动A之后,我没有在后面的堆栈中获得B和C


0

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

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

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


0

在意图中添加NO History Flag。

在活动B中,如下启动活动C >>>>>>

Intent intent = new Intent(this, C.class);
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY); 
startActivity(intent);
finish();

0

在清单中

android:launchMode="singleTask"

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

0

无论是添加到您Activity BActivity C

android:noHistory="true"

Override onBackPressed功能是避免用return

@Override
public void onBackPressed() {
   return;
}

0

使用setFlags()方法清除背面打开的所有活动并启动yourActvity

Intent intent = new Intent(getApplicationContext(), yourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.