你如何使用Intent.FLAG_ACTIVITY_CLEAR_TOP清除活动堆栈?

piu*_*lte 76 java android android-manifest android-intent android-activity

我已经阅读了几篇关于使用它的帖子,但必须遗漏一些因为它不适合我.我的活动A在清单中有launchmode ="singleTop".它启动活动B,启动模式="singleInstance".活动B打开浏览器并接收和意图返回,这就是为什么它是singleInstance.我试图覆盖后退按钮,以便用户被发送回活动A,然后可以按Back返回活动,而不是再次返回活动B.

// activity B
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
 if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR
  && keyCode == KeyEvent.KEYCODE_BACK
  && event.getRepeatCount() == 0) onBackPressed();
 return super.onKeyDown(keyCode, event);
}
@Override
public void onBackPressed() {
 startActivity(new Intent(this, UI.class)
 .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
 return;
}
Run Code Online (Sandbox Code Playgroud)

从浏览器返回后,堆栈是...... A,B,浏览器,B

我希望这段代码能够将堆栈更改为...... A ...以便再次按下后再将用户带回主屏幕.

相反,它似乎将堆栈更改为... A,B,浏览器,B,A ......好像那些标志不在那里.

我尝试在startActivity之后调用活动B中的finish(),但后面的按钮再次将我带回浏览器!

我错过了什么?谢谢!

Jes*_*sen 103

我已经开始活动A-> B-> C-> D. 当按下后退按钮时,活动DI想要进入活动A.由于A是我的起点,因此已经在堆栈中,A顶部的所有活动都被清除,你不能回到A的任何其他活动.

这实际上适用于我的代码:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        Intent a = new Intent(this,A.class);
        a.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(a);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}       
Run Code Online (Sandbox Code Playgroud)

  • 该解决方案关闭了所有中间活动;而且,重新启动RootActivity。您可以在下面查看@Steel_Fedex的解决方案。它执行相同的操作,但不会重新启动RootActivity。 (3认同)

Sco*_*ris 65

@bitestar有正确的解决方案,但还有一个步骤:

它被隐藏在文档中,但是你必须将launchModeActivity改为除了之外的任何东西standard.否则它将被销毁并重新创建,而不是重置到顶部.

  • 实际上......`Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP`就是这么做的. (49认同)
  • 那么 Steel_fedex 的解决方案到底在哪里?! (4认同)

Fed*_*ana 19

为此,我使用FLAG_ACTIVITY_CLEAR_TOP标志启动Intent
(没有FLAG_ACTIVITY_NEW_TASK)

launchMode = "singleTask"在发布活动的清单中.

看起来它像我需要的那样工作 - 活动不会重新启动,所有其他活动都会关闭.


Dar*_*pan 10

虽然这个问题已经有了足够的答案,但我想有人会想知道为什么这个标志以这种特殊的方式工作,这就是我在Android文档中找到的

上面示例中当前运行的活动B实例将在其onNewIntent()方法中接收您从此处开始的新意图,或者本身已完成并使用新意图重新启动.

如果它已将其启动模式声明为"多个"(默认值)并且您没有在同一意图中设置FLAG_ACTIVITY_SINGLE_TOP,那么它将被完成并重新创建; 对于所有其他启动模式或如果设置了FLAG_ACTIVITY_SINGLE_TOP,则此Intent将被传递到当前实例的onNewIntent().


所以,要么,
1.launchMode从标准(即.singleTask或某事物)将活动A 更改为其他内容.那么你的旗帜FLAG_ACTIVITY_CLEAR_TOP将不会重新启动你的活动A.

要么,

2.使用Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP为您的标志.然后它会以你想要的方式工作.


Hou*_*lla 9

我使用三个标志来解决问题:

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
                Intent.FLAG_ACTIVITY_CLEAR_TASK | 
                Intent.FLAG_ACTIVITY_NEW_TASK);
Run Code Online (Sandbox Code Playgroud)