ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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


E
Ev0lv3zz

尝试按照 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.

谢谢,但我试过这个。仍然当我再次显示 C 后点击返回按钮时。我能错过什么?
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
对我不起作用,但是在源活动上调用 finish() 可以实现我需要实现的目标
我遇到了同样的问题,这不起作用。为我解决的问题是在开始新活动后调用 finish()
我还添加了一个更清晰的 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);开始活动(意图);结束();
P
Philippe A
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

关于 CLEAR_TOP 标志的所有方面 - 此组合是唯一完全清除整个堆栈并使新活动成为应用程序中唯一的组合。谢谢!
这与接受的答案有什么区别?
谢谢,与已接受答案的区别在于,有了这个标志,我们不需要调用 activity.finish
FLAG_ACTIVITY_CLEAR_TASK 与 NEW_TASK 完美配合
这应该是公认的答案。非常感谢。
B
Bhunnu Baba

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

android:noHistory="true"

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


使用时要非常小心 - 如果您使用 FB 登录或任何类似的功能
@Skynet 为什么?这样做有什么问题?
当您将控制权传递给 FB 以从 nohistory 为 true 的页面登录时,FB 应用程序在用户登录后现在无法登陆,在我的情况下,它正在返回手机主屏幕,我差点丢了工作!
这不会让活动添加到 backstack....这不是正确的解决方案。
正是我在寻找
G
Geng Jiawen

这困扰了我很长时间。最后我通过这样做解决了这个问题:

在片段中,使用:

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 = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

如果您使用的是androidannotations,则必须添加:Intent.FLAG_ACTIVITY_CLEAR_TASK
活动解决方案对我来说效果很好。尽管我认为使用 API 16,Daniel Schuler 的解决方案更容易。
谢谢yosafatade,这就是我所缺少的!
D
Daniel Schuler

从 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,这是一个非常有用且简单的解决方案。为我工作!
提醒:这仅适用于共享相同 taskAffinity 名称的活动
仅当您在历史记录中只有一项活动时,这才有效。
J
Joseph Earl

将 android:launchMode="singleTop" 添加到 Activity A 清单中的 Activity 元素 然后在启动 Activity A 时使用 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) 和 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

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


是的。这就是我现在正在使用的,但它并没有这样做。当我按下后退按钮时,仍然出现 C。
奇怪的是,我在一个项目中使用了它,它工作正常......按下返回将我带到主屏幕。也许还有其他事情发生。你能发布你的清单吗?
我重新启动了模拟器,现在它似乎就像你说的那样工作。非常感谢你的帮助!
singleTop 应该与清除堆栈无关。
c
cagdasalagoz

尝试使用

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

并不是

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

这行得通。我的假设是使用 setFlags 将替换所有默认设置标志,但事实并非如此
J
Jaydeep purohit

如果您的应用程序具有最低 sdk 版本 16,那么您可以使用 finishAffinity()

在当前任务中完成此活动以及紧接其下的所有具有相同亲和力的活动。

这对我有用 在 Top Payment 屏幕中删除所有后台活动,

 @Override
public void onBackPressed() {
         finishAffinity();
        startActivity(new Intent(PaymentDoneActivity.this,Home.class));
    } 

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


C
Community

根据 Removing an activity from the history stack 中的 Wakka...

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

    <activity android:name=".MyActivity"
        android:noHistory="true">
    </activity>

B
Biswajit_86

为了将来的研究,试试这个代码。

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()。仅仅关闭你自己的应用程序就很麻烦。
b
baswaraj

使用finishAffinity();在任务 C 中启动任务 A 以清除 backstack 活动。


只有这个答案对我有用。 Intent.FLAG_ACTIVITY_CLEAR_TOP 和 Intent.FLAG_ACTIVITY_NEW_TASK 不是必需的
F
Firzan Shaikh
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.

M
Manaus

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

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

A
Adeel

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

finishAffinity();
finish();

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


E
Exigente05

在 kotlin 中,它几乎与 java 相同。只有 |符号替换为或文本。所以,它是这样写的——

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

i
ianjoyner

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

由于 A 是根活动,仅使用 FLAG_ACTIVITY_CLEAR_TOP 从 B 或 C 启动它确实会从后台堆栈中删除 B 和 C。


c
cagdasalagoz

在我看来,您需要使用 startActivityForResult()Activity B 开始 Activity C。当您单击 Activity C 中的按钮时,调用 setResult(RESULT_OK)finish() 以结束 Activity C。在 Activity B 中,您可以通过调用 finish() 来让 onActivityResult() 做出响应,然后您将返回到 Activity A


是的,但是如果 A 和 C 之间有 42 个活动,这将是相当乏味的。标志 FLAG_ACTIVITY_CLEAR_TOP 应该直接执行 OP 想要的操作。
这将不是实现OP想要的最佳方式,正如@Guillaume所说,它需要在根和堆栈顶部之间的所有活动中使用代码。
妥当注明。这些显然是我需要了解的标志。
G
Gibolt

高级、可重用的 Kotlin:

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

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
}

c
cagdasalagoz

我尝试了所有解决方案,但没有一个适合我。我的解决方案是:

在 Android 清单中使用 [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();

c
cagdasalagoz

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

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


s
stevyhacker

科特林示例:

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

A
Abhijeet

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


M
Mujeeb Rahaman T
 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);

M
Mohamed Mo'nes

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

c
cagdasalagoz

您可以使用此示例从 Activity C 调用您的 Activity A

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


A
Arnaud

之后你不会有任何活动按下后退按钮:

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

j
james

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

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


这只会影响堆栈顶部的活动,而不是它的根。
S
Sathesh

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

在使用标志 FLAG_ACTIVITY_CLEAR_TOP 启动活动 A 后,我没有在后台堆栈中获得 B 和 C


S
Swap-IOS-Android

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

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

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


A
Arun Sharma

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

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

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