Android:打开活动时不将其保存在栈中

100
我的两个活动是:主要和列表。
你可以从主要打开列表;也可以从列表打开主要。
我希望每次打开列表时,它不会保存到“历史记录”中。因此,从主要页面返回不能返回到列表。
这是否可能?

13
如果list启动于main,那么在startActivity(...)之后立即调用finish()函数。这样如果用户从main返回,则不会有任何可以返回的内容。 - Squonk
这是关于通知导航的内容,但其中的概念可能适用于其他方面。http://developer.android.com/guide/topics/ui/notifiers/notifications.html#NotificationResponse - Kevin Lee
请接受在启动下一个活动后调用 finish() 来结束当前活动的建议! - user2297550
11个回答

173

当启动列表的Activity时,应按如下设置其Intent标志:

Intent i = new Intent(...); // Your list's Intent
i.setFlags(i.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY); // Adds the FLAG_ACTIVITY_NO_HISTORY flag
startActivity(i);

FLAG_ACTIVITY_NO_HISTORY标志可以防止新的Activity被添加到历史记录堆栈中。

NB:正如@Sam指出的那样,您可以改用i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);。这没有功能上的区别。


2
对于这个方法,只是有一点评论:如果只有两个Activity的话,这个方法将完美地工作。 但是,如果列表Activity能够启动另一个Activity(比如第三个Activity),在第三个Activity中按返回按钮将返回到主Activity而不是列表Activity。 - VinceFR
1
不过设置FLAG_ACTIVITY_NEW_TASK标志位就可以了,列表Activity会被添加到历史记录中,但始终位于顶部,因此从主Activity返回时不会显示列表Activity。 - VinceFR
7
你使用 setFlags()getFlags() 而不是 Intent.addFlags() 有什么特别的原因吗? - Sam
1
@VinceFR 这正是我想要的!从 a 到 b 再到 c,并直接返回 c。 - realtebo
很遗憾,FLAG_ACTIVITY_NO_HISTORY 对我没有起作用。在我的示例中,我使用上述标志启动一个意图,然后当单击返回时,先前使用意图启动的应用程序仍然在后台堆栈中。 - AdamHurwitz
显示剩余5条评论

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

指向您不想保留在堆栈中的活动。


启动活动时使用no_history标志有什么区别吗? - realtebo
1
就像你在问题中所说的“每次打开列表时都不会保存到'历史记录'”,因此无论何时再次打开应用程序,都将带您进入主活动。 - Marcin S.
@MarcinS. 当应用程序不在最近的应用程序列表中时,它无法工作。您能否解释一下为什么会发生这种情况? - Ajit Kumar Dubey
1
那么这两种方法(清单和标志)之间有什么区别呢? - pumbosha
@pumbosha Manifest方法总是会将Activity从历史记录中排除。而标志方法可以让您在运行时控制该行为。 - John Crawford
当我在这个活动中添加了一些内容并请求某些权限时,我的应用程序崩溃了,但没有日志记录(Kotlin)。 - ghita

30

1
这很好,但有没有办法停止系统的扫描“更改任务”动画?不幸的是,添加FLAG_ACTIVITY_NO_ANIMATION并不能阻止它! - androidguy
这会影响应用程序的速度吗? - Acauã Pitta

27

如果您在打开另一个活动后立即调用finish(),则被完成的那个活动将从堆栈中删除。

例如:

Intent intent = new Intent(this, NextActivity.class);
startActivity(intent);
finish();

如果你的手机不够快,你会看到之前的活动正在消失。 - Nolan
@Nolan,那只有在你开始活动之前完成才行。 - Henrik Bøgelund Lavstsen
这是最好的答案!拜托接受它吧! - user2297550

11

在我的特定情况下,FLAG_ACTIVITY_NO_HISTORY无效。单独使用FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TASK也无效。

然而,FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TASK一起使用有效。

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

不是这个问题的答案,但正是我在寻找的! - Daveloper

6
晚了一步,但是这个答案可以为其他答案增加些深度。一切都取决于你想从该活动开始的其他活动中发生什么。
选项1-只有这一个活动不应该有调用活动的历史记录
那么只需执行以下操作:
Intent i = new Intent(...);
i.addFlag(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(i);

选项2 - 所有从特定活动开始的活动不应该有历史记录。
然后在调用活动的清单中添加以下内容:
android:noHistory="true" 

但如果你确实想在新的活动中保留历史记录,那么你就需要手动移除标志:

Intent i = new Intent(...);
i.removeFlag(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(i);

希望这可以澄清其他答案 :)

4

我想补充一种用Kotlin实现的方法:

val i = Intent(this, LogInActivity::class.java)
startActivity(i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK))

2
更符合 Kotlin 风格的写法: ```Intent(this, MainActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) }.also { startActivity(it) }``` - 4ndro1d

3

如果活动已经在运行,请尝试使用FLAG_ACTIVITY_CLEAR_TOP:

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


0

情况:1

使用此标志

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

在这种情况下,活动转换不流畅,在启动活动之前会出现空白白页。

案例2:

Intent intent = new Intent(this, NextActivity.class);
startActivity(intent);
finish();

如果你的手机不够快,你会看到之前的活动正在消失,我希望今天大多数设备都能解决这个问题。


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