Android:清除后台堆栈

在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并清除back堆栈(关闭B和C)。所以当用户使用后退按钮B和C不会出现时,我一直在尝试以下方法:

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

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

297526 次浏览

在我看来,你需要使用startActivityForResult()Activity B开始Activity C。当你点击Activity C中的按钮时,调用setResult(RESULT_OK)finish(),这样Activity C就结束了。在Activity B中,你可以让onActivityResult()通过对自身调用finish()来响应,然后你会被带回Activity B0。

尝试按照文档中描述的为FLAG_ACTIVITY_CLEAR_TOP添加FLAG_ACTIVITY_NEW_TASK:

此启动模式也可用于 配合使用效果好 FLAG_ACTIVITY_NEW_TASK:如果使用 启动一个任务的根活动it 会不会带来目前的运行 实例的 前景,然后清除到它的 根的状态。这个特别有用, 例如,当启动 来自通知的活动 经理。< / p >

所以你启动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.

除了FLAG_ACTIVITY_CLEAR_TOP之外,你还可以尝试添加Intent.FLAG_ACTIVITY_SINGLE_TOP:

< p > intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); < / p >
  1. android:launchMode="singleTop"添加到活动A的清单中的活动元素
  2. 然后使用intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)和 当启动活动A时intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

这意味着当活动A启动时,它上面的所有任务都被清除,这样活动A就在上面。一个新的后台堆栈被创建,其中A位于根,并且使用singleTop确保你只启动A一次(因为A现在由于..._CLEAR_TOP而位于顶部)。

为相关活动添加清单文件怎么样?

android:noHistory="true"

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

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

如果A是根活动,那么只有使用FLAG_ACTIVITY_CLEAR_TOP从B或C启动它才会从后台堆栈中删除B和C。

根据从历史堆栈中删除一个活动中的Wakka


android:noHistory="true"属性添加到AndroidManifest.xml中的<activity>中,如下所示:

    <activity android:name=".MyActivity"
android:noHistory="true">
</activity>
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Intent intent = new Intent(this, A.class);
startActivity(intent);
finish();

给定的代码可以正常工作。我在应用程序生命周期示例中尝试过。

我没有得到B和C在后面的堆栈开始活动A与标志,FLAG_ACTIVITY_CLEAR_TOP

试着用

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

而不是

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

从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 < / p >

< p > logout.addFlags (Intent.FLAG_ACTIVITY_CLEAR_TASK); logout.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK); < / p >

这个问题困扰了我很长一段时间。最后我是这样解决的:

在片段中,使用:

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

在Activity中,使用(与fragment相比,多添加一个intent标志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);

我在开始新的意图后调用activity_name.this.finish(),它为我工作。

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

但这对我没用……我不建议使用这个解决方案,但如果设置标志不适合你,你可以试试这个..但我仍然建议不要使用它

对于未来的研究,请尝试此代码。

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();

在意图中添加NO历史标志。

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

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

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

更多细节请查看文档。

或者将此添加到Activity BActivity C

android:noHistory="true"

Override onBackPressed函数,以避免使用return进行背压。

@Override
public void onBackPressed() {
return;
}
如果你的应用程序有最低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

我尝试了所有的解决方案,没有一个单独对我有效。 我的解决方案是:

在Android manifest中使用[android:launchMode="singleTop"]Activity A声明为SingleTop

现在,在从任何地方启动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();

你可以使用这个例子从Activity C调用你的Activity A

Intent loout = new Intent(context, LoginActivity.class); loout.setFlags(意图。| Intent.FLAG_ACTIVITY_CLEAR_TASK; context.startActivity (loout); < /代码> < / p >

在清单

android:launchMode="singleTask"

而且

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

使用finishAffinity ();在任务C中启动任务A,清除后台活动。

使用此代码启动一个新的活动,并关闭或销毁所有其他活动堆栈或回栈。

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

使用setFlags()方法清除背面打开的所有活动关闭和开始 youractivity

Intent intent = new Intent(getApplicationContext(), yourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

这是一个非常老的答案,我并没有真正找到一个适当的解决方案,以清除backStack的唯一目的,我决定创建自己的backStack,这甚至不是一个堆栈tbh,但它不必是,因为我们想要清除它的一切;

每次都有一个把手的背架的开销,但它给了我需要的控制;


首先声明一个公共的静态活动列表(或片段,无论你需要什么);

public static ArrayList <Activity> backStack = new ArrayList<>();

在所有其他活动的onCreate方法中:

MainActivity.backStack.add(this);

最后,当你想要清除backstack时,简单地调用:

public static void killBackStack () {
for (Activity ac : backStack) {
if (ac != null)
ac.finish();
}
}
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.

这为我的onBackPressed工作:

public void onBackPressed()
{
Intent intent = new Intent(ImageUploadActivity.this, InputDataActivity.class);


Intent myIntent = new Intent(this, ImageUploadActivity.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}

我发现了一个有趣的解决办法,可能会有帮助。我在onBackPressed()方法中做到了这一点。

finishAffinity();
finish();

FinishAffinity删除现有活动到其堆栈的连接。然后finish帮助你退出那个活动。最终将退出应用程序。

在kotlin中,它几乎与java相同。只有|符号被文本替换。 它的写法是-

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

芬兰湾的科特林的例子:

      val intent = Intent(this@LoginActivity, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
finish()

我是这样解决这个问题的:

private boolean clearHistoryBackStack = true;


@Override
public final void finish() {
super.finish();


if(clearHistoryBackStack)
finishAffinity();
}

这段代码为我在kotlin工作:

 val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
finish()

对我来说,添加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();

高级、可重用的Kotlin:

您可以直接使用setter方法设置标志。在Kotlin中,or是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之前直接调用这个函数

intent.clearStack()

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

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

你不会得到任何活动按后退按钮之后:

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK |
Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finishAffinity();
finish();

尽管这可能来得晚了。当我试图从活动A中解脱出来时,我也遇到了同样的问题。B→C→D,然后到B如果D返回真,我想清除活动D和C。

val intent = Intent(this, ActivityUpload::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(intent)

我得到了文档中描述的解决方案。

例如,考虑一个由下列活动组成的任务:a、B、C、D。如果D调用startActivity()时带有一个解析为活动B的组件的Intent,那么C和D将被完成,B接收到给定的Intent,导致堆栈现在是:a, B。