如何将一个活动带到前台(堆栈顶部)?

95

在Android中,我定义了一个名为ExampleActivity的活动。

当我的应用程序启动时,它会创建该A-Activity的一个实例,假设它是A。当用户在A中点击按钮时,将创建另一个B-Activity的实例,即B。此时任务堆栈为B-A,B位于顶部。然后,用户在B上点击一个按钮,另一个C-Activity的实例将被创建。现在任务堆栈是C-B-A,C位于顶部。

现在,当用户在C上点击按钮时,我希望应用程序将A置于前台,即使A处于任务堆栈的顶部,变成A-C-B。

如何编写代码来实现这一点?

10个回答

117

3
我认为应该使用FLAG_ACTIVITY_SINGLE_TOP - user942821
27
在这里,FLAG_ACTIVITY_SINGLE_TOP是无法帮助的。当ActivityC在堆栈顶部并调用startActivity()启动ActivityA时,即使您设置了FLAG_ACTIVITY_SINGLE_TOP,它仍将创建ActivityA的新实例FLAG_ACTIVITY_SINGLE_TOP只有在尝试启动已经在堆栈顶部的活动时,才会防止创建一个新实例。在这种情况下,ActivityA不在堆栈顶部,因此Android会创建一个新实例。 - David Wasser
7
太棒了!使用(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP)来清除特定活动页面之后的所有历史记录。 - shkschneider
11
如果您同时指定FLAG_ACTIVITY_CLEAR_TOP,那么FLAG_ACTIVITY_REORDER_TO_FRONT将被忽略。请查阅文档。 - Kris Subramanian
3
如果你想把活动置于回退栈的顶部而不是前台,且该活动已在用户会话中,则使用intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP)即可。这将能够正常工作。 - Hassan Jamil
“reorder to front” 会在 onNewIntent 中传递新的 Intent 吗? - Bhargav

67

我发现最好的方法是使用与Android主屏幕相同的意图 - 应用启动器。

例如:

Intent i = new Intent(this, MyMainActivity.class);
i.setAction(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(i);

这样,用户最近使用的我的应用程序中的任何活动都会再次显示在前面。我发现这对于使用我的服务的PendingIntent将用户带回我的应用程序非常有用。


2
非常感谢您提供的那段代码。我浪费了好几个小时才让它正常工作。 - PakitoV
3
可以不用ComponentName和setComponent,而是使用新的Intent(this, MyMainActivity.class)。 - Tima
3
奇怪的是,只有这个方法适用于我;设置标志没有起作用并且总是重新创建了这个活动。 - Steven Huang
6
当我阅读这个回答和评论时,很明显我们有一个误解。原始问题询问如何重新排列任务栈中的“Activity”。提问者明确表示他想将“ActivityA”从堆栈底部移动到堆栈顶部(即:他想将“ActivityA重新排序到任务栈的前面”)。这个答案不会做到那一点。这个答案是回答“如何将我的应用程序(任务栈)从后台切换到前台?”的问题。这与提问者原来的问题完全不同。 - David Wasser
3
赞同按钮上写着“This answer is helpful”,而不是“This answer is helpful to the op”——对于这种情况,他/她已经有了“接受标记”。显然,我不知道对于提问者来说什么是有帮助的。依据我猜测提问者会认为什么有用而对答案进行踩是不正确的(IMHO)。 - Boris Treukhov
显示剩余8条评论

29

以下是一个示例代码,演示如何实现:

Intent intent = getIntent(getApplicationContext(), A.class)

这将确保您在堆栈中只有一个活动实例。

private static Intent getIntent(Context context, Class<?> cls) {
    Intent intent = new Intent(context, cls);
    intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
    return intent;
}

13

FLAG_ACTIVITY_REORDER_TO_FRONT: 如果在传递给 Context.startActivity() 的 Intent 中设置了此标志,则如果已经运行,则启动的活动将被带到其任务历史堆栈的前面。

Intent i = new Intent(context, AActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(i);

4
我认为结合使用Intent标志应该可以解决问题。特别是Intent.FLAG_ACTIVITY_CLEAR_TOPIntent.FLAG_ACTIVITY_NEW_TASK
在调用startActivity之前,将这些标志添加到您的意图中。

2

i.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);

注意:你的homeactivity启动模式应该是single_task。


1
一般来说,我认为不推荐使用这种活动管理方法。重新激活堆栈中两个步骤之前的活动存在问题,因为该活动很可能已被销毁。我的建议是记住您的活动状态,并使用startActivity()启动它们。
我相信您已经看过这个页面,但为了方便起见,这里是链接

0

如果你想在点击通知时将一个活动带到堆栈的顶部,那么你可能需要执行以下操作使FLAG_ACTIVITY_REORDER_TO_FRONT起作用:

对我来说,解决方案是创建一个广播接收器来监听通知触发的广播操作。基本上是这样的:

  1. 通知触发一个广播操作,并附带要启动的活动名称。

  2. 当点击通知时,广播接收器捕获此操作,然后使用FLAG_ACTIVITY_REORDER_TO_FRONT标志创建一个意图来启动该活动。

  3. 活动被带到活动堆栈的顶部,没有重复。


0
如果您使用adb am cmd进行启动,则应该像下面这样使用cmd。
adb shell am start -n com.xxx.xxx/com.xxx.Activity --activity-reorder-to-front 

adb意图参数

adb意图-f参数描述


-2
如果你正在使用“Google Cloud Message”和“PendingIntent”类来接收推送通知,下面的代码只会在操作栏中显示通知。
点击通知时不会创建任何活动,最后一个活动将被恢复并保留当前状态,没有任何问题。
``` Intent notificationIntent = new Intent(this, ActBase.class); notificationIntent.setAction(Intent.ACTION_MAIN); notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); ```
``` NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Localtaxi") .setVibrate(vibrate) .setStyle(new NotificationCompat.BigTextStyle().bigText(msg)) .setAutoCancel(true) .setOnlyAlertOnce(true) .setContentText(msg); ```

mBuilder.setContentIntent(contentIntent);

NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);

mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());

你好!


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