首页 文章

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

提问于
浏览
72

我已经阅读了几篇关于使用它的帖子,但必须遗漏一些因为它不适合我 . 我的活动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;
}

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

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

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

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

我错过了什么?谢谢!

10 回答

  • 1

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

    它隐藏在文档中,但您必须将 ActivitylaunchMode 更改为 standard 以外的任何内容 . 否则它将被销毁并重新创建,而不是重置到顶部 .

  • 61

    我已经开始活动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);
    }
    
  • 0

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

    和已启动活动的清单中的 launchMode = "singleTask" .

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

  • 1

    虽然这个问题已经有了足够的答案,但我想有人会想知道为什么这个旗子以这种奇特的方式运作,这就是我在Android documentation中找到的

    上面示例中当前运行的活动B实例将在其onNewIntent()方法中接收您从此处开始的新意图,或者本身已完成并使用新意图重新启动 . 如果它已将其启动模式声明为“多个”(默认值)并且您没有在同一意图中设置FLAG_ACTIVITY_SINGLE_TOP,那么它将被完成并重新创建;对于所有其他启动模式或如果设置了FLAG_ACTIVITY_SINGLE_TOP,则此Intent将被传递到当前实例的onNewIntent() .

    所以,要么,
    1 . 将活动A的 launchMode 更改为标准的其他内容(即 singleTask 或其他内容) . 然后您的标志 FLAG_ACTIVITY_CLEAR_TOP 将不会重新启动您的活动A.

    要么,

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

  • 2

    我知道有没有看到OP如何工作,因为我不认为FLAG_ACTIVITY_CLEAR_TOP在他的特定情况下是有意义的 . 该标志仅与 same task 中的活动相关 . 基于他的描述, each activity is in its own task :A,B和浏览器 .

    可能会让他失望的是A是singleTop,当它应该是singleTask时 . 如果A是singleTop,而B开始A,那么将创建一个新的A,因为A不在B的任务中 . 从singleTop的文档:

    “如果活动的实例已存在于 current task 的顶部,则系统会将意图路由到该实例......”

    由于B启动A,当前任务是B的任务,它是针对singleInstance的,因此不能包含A.使用singleTask在那里实现所需的结果,因为系统将找到具有A的任务并将该任务带到前台 .

    最后,在B启动A并且用户从A按下后,OP不希望看到B或浏览器 . 为此,在B中调用finish()是正确的;再次,FLAG_ACTIVITY_CLEAR_TOP赢得了't remove the other activities in A'的任务,因为他的其他活动都在不同的任务中 . 但他缺少的部分是B在触发浏览器的意图时也应该使用FLAG_ACTIVITY_NO_HISTORY . Note: 如果浏览器在启动OP的应用程序之前已经运行,那么当然从A回来时你会看到浏览器 . 所以要真正测试它,一定要在启动应用程序之前退出浏览器 .

  • 18

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

    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
                    Intent.FLAG_ACTIVITY_CLEAR_TASK | 
                    Intent.FLAG_ACTIVITY_NEW_TASK);
    
  • 9

    FLAG_ACTIVITY_NEW_TASK是一个问题,它启动一个新任务 . 除去它,你就完成了 .

    好吧,我建议你在使用它们之前阅读每个Flag的功能

    阅读thisIntent Flags here

  • 2

    最初我也遇到了使FLAG_ACTIVITY_CLEAR_TOP工作的问题 . 最终我通过使用它的值(0x04000000)使它工作 . 所以看起来有一个Eclipse /编译器问题 . 但不幸的是,幸存的活动重新开始,这不是我想要的 . 所以看起来没有简单的解决方案 .

  • 1

    在清单文件中添加android:noHistory =“true” .

    <manifest >
            <activity
                android:name="UI"
                android:noHistory="true"/>
    
    </manifest>
    
  • 101

    我在启动新意图后打电话给 activity_name.this.finish() ,它对我有用 .

    I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"
    

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

相关问题