简体   繁体   English

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

[英]How do you use Intent.FLAG_ACTIVITY_CLEAR_TOP to clear the Activity Stack?

I've read through several posts about using this, but must be missing something as it's not working for me. 我已经阅读了几篇关于使用它的帖子,但必须遗漏一些因为它不适合我。 My activity A has launchmode="singleTop" in the manifest. 我的活动A在清单中有launchmode =“singleTop”。 It starts activity B, with launchmode="singleInstance". 它启动活动B,启动模式=“singleInstance”。 Activity B opens a browser and receives and intent back, which is why it's singleInstance. 活动B打开浏览器并接收和意图返回,这就是为什么它是singleInstance。 I'm trying to override the back button so that the user is sent back to the activity A, and can then press Back to leave the activity, rather than back to activity B again. 我试图覆盖后退按钮,以便用户被发送回活动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;
}

After returning from the browser, the stack is... A,B,Browser,B 从浏览器返回后,堆栈是...... A,B,浏览器,B

I expect this code to change the stack to... A ... so that pressing back once more takes the user back to the Home Screen. 我希望这段代码能够将堆栈更改为...... A ...以便再次按下后再将用户带回主屏幕。

Instead it seems to change the stack to... A,B,Browser,B,A ...as though those flags aren't there. 相反,它似乎将堆栈更改为... A,B,浏览器,B,A ......好像那些标志不在那里。

I tried calling finish() in activity B after startActivity, but then the back button takes me back to the browser again! 我尝试在startActivity之后调用活动B中的finish(),但后面的按钮再次将我带回浏览器!

What am I missing? 我错过了什么? Thank you! 谢谢!

I have started Activity A->B->C->D. 我已经开始活动A-> B-> C-> D. When the back button is pressed on Activity DI want to go to Activity A. Since A is my starting point and therefore already on the stack all the activities in top of A is cleared and you can't go back to any other Activity from A. 当按下后退按钮时,活动DI想要转到活动A.由于A是我的起点,因此已经在堆栈中,A顶部的所有活动都被清除,你不能回到A的任何其他活动。

This actually works in my code: 这实际上适用于我的代码:

@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);
}       

@bitestar has the correct solution, but there is one more step: @bitestar有正确的解决方案,但还有一个步骤:

It was hidden away in the docs, however you must change the launchMode of the Activity to anything other than standard . 它隐藏在文档中,但是您必须将ActivitylaunchMode更改为standard以外的任何内容。 Otherwise it will be destroyed and recreated instead of being reset to the top. 否则它将被销毁并重新创建,而不是重置到顶部。

For this, I use FLAG_ACTIVITY_CLEAR_TOP flag for starting Intent 为此,我使用FLAG_ACTIVITY_CLEAR_TOP标志来启动Intent
(without FLAG_ACTIVITY_NEW_TASK ) (没有FLAG_ACTIVITY_NEW_TASK

and launchMode = "singleTask" in manifest for launched activity. 启动活动的清单中的launchMode = "singleTask"

Seems like it works as I need - activity does not restart and all other activities are closed. 似乎它按我的需要工作 - 活动不会重新启动,所有其他活动都会关闭。

Though this question already has sufficient answers, I thought somebody would want to know why this flag works in this peculiar manner, This is what I found in Android documentation 虽然这个问题已经有了足够的答案,但我想有人会想知道为什么这个标志以这种特殊的方式工作,这就是我在Android文档中找到的

The currently running instance of activity B in the above example will either receive the new intent you are starting here in its onNewIntent() method, or be itself finished and restarted with the new intent. 上面示例中当前运行的活动B实例将在其onNewIntent()方法中接收您从此处开始的新intent,或者本身已完成并使用新intent重新启动。

If it has declared its launch mode to be "multiple" (the default) and you have not set FLAG_ACTIVITY_SINGLE_TOP in the same intent, then it will be finished and re-created; 如果它已将其启动模式声明为“多个”(默认值)并且您没有在同一意图中设置FLAG_ACTIVITY_SINGLE_TOP,那么它将被完成并重新创建; for all other launch modes or if FLAG_ACTIVITY_SINGLE_TOP is set then this Intent will be delivered to the current instance's onNewIntent(). 对于所有其他启动模式或如果设置了FLAG_ACTIVITY_SINGLE_TOP,则此Intent将被传递到当前实例的onNewIntent()。


So, Either, 所以,要么,
1 . 1 Change the launchMode of the Activity A to something else from standard (ie. singleTask or something). 将Activity A的launchMode从标准(即singleTask或其他)更改为其他内容。 Then your flag FLAG_ACTIVITY_CLEAR_TOP will not restart your Activity A. 然后您的标志FLAG_ACTIVITY_CLEAR_TOP将不会重新启动您的活动A.

or, 要么,

2 . 2 Use Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP 使用Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP as your flag. Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP作为你的旗帜。 Then it will work the way you desire. 然后它会以你想要的方式工作。

I use three flags to resolve the problem: 我使用三个标志来解决问题:

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

I know that there's already an accepted answer, but I don't see how it works for the OP because I don't think FLAG_ACTIVITY_CLEAR_TOP is meaningful in his particular case. 我知道已经有一个已接受的答案,但我不知道它对OP有何影响,因为我不认为FLAG_ACTIVITY_CLEAR_TOP在他的特定情况下是有意义的。 That flag is relevant only with activities in the same task . 该标志仅与同一任务中的活动相关。 Based on his description, each activity is in its own task : A, B, and the browser. 根据他的描述, 每个活动都有自己的任务 :A,B和浏览器。

Something that is maybe throwing him off is that A is singleTop, when it should be singleTask. 可能会让他失望的是A是singleTop,当它应该是singleTask时。 If A is singleTop, and B starts A, then a new A will be created because A is not in B's task. 如果A是singleTop,而B开始A,那么将创建一个新的A,因为A不在B的任务中。 From the documentation for singleTop: 从singleTop的文档:

"If an instance of the activity already exists at the top of the current task , the system routes the intent to that instance..." “如果活动的实例已存在于当前任务的顶部,则系统会将意图路由到该实例......”

Since B starts A, the current task is B's task, which is for a singleInstance and therefore cannot include A. Use singleTask to achieve the desired result there because then the system will find the task that has A and bring that task to the foreground. 由于B启动A,当前任务是B的任务,它是针对singleInstance的,因此不能包含A.使用singleTask在那里实现所需的结果,因为系统将找到具有A的任务并将该任务带到前台。

Lastly, after B has started A, and the user presses back from A, the OP does not want to see either B or the browser. 最后,在B启动A并且用户从A按下后,OP不希望看到B或浏览器。 To achieve this, calling finish() in B is correct; 为此,在B中调用finish()是正确的; again, FLAG_ACTIVITY_CLEAR_TOP won't remove the other activities in A's task because his other activities are all in different tasks. 再次,FLAG_ACTIVITY_CLEAR_TOP将不会删除A任务中的其他活动,因为他的其他活动都在不同的任务中。 The piece that he was missing, though is that B should also use FLAG_ACTIVITY_NO_HISTORY when firing the intent for the browser. 但他缺少的部分是B在触发浏览器的意图时也应该使用FLAG_ACTIVITY_NO_HISTORY。 Note: if the browser is already running prior to even starting the OP's application, then of course you will see the browser when pressing back from A. So to really test this, be sure to back out of the browser before starting the application. 注意:如果浏览器在启动OP的应用程序之前已经运行,那么当然从A回来时你会看到浏览器。所以要真正测试它,一定要在启动应用程序之前退出浏览器。

i called activity_name.this.finish() after starting new intent and it worked for me. 我在启动新意图后调用了activity_name.this.finish() ,它对我有用。

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

But it won't work for me... I am not suggesting this solution for use but if setting flag won't work for you than you can try this..But still i recommend don't use it 但它对我不起作用......我不建议使用这个解决方案,但如果设置标志对你不起作用,你可以尝试这个..但我仍然建议不要使用它

Add android:noHistory="true" in manifest file . 在清单文件中添加android:noHistory =“true”。

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

</manifest>

FLAG_ACTIVITY_NEW_TASK is the problem here which initiates a new task .Just remove it & you are done. FLAG_ACTIVITY_NEW_TASK是一个问题,它启动一个新任务。除去它,你就完成了。

Well I recommend you to read what every Flag does before working with them 好吧,我建议你在使用它们之前阅读每个Flag的功能

Read this & Intent Flags here 在这里阅读这个Intent Flags

Initially I also had problem getting FLAG_ACTIVITY_CLEAR_TOP to work. 最初我也遇到了使FLAG_ACTIVITY_CLEAR_TOP工作的问题。 Eventually I got it to work by using the value of it (0x04000000). 最终我通过使用它的值(0x04000000)使它工作。 So looks like there's an Eclipse/compiler issue. 所以看起来有一个Eclipse /编译器问题。 But unfortunately the surviving activity is restarted, which is not what I want. 但不幸的是,幸存的活动重新开始,这不是我想要的。 So looks like there's no easy solution. 所以看起来没有简单的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM