清除整个历史堆栈并在 Android 上启动一个新活动
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3473168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Clear the entire history stack and start a new activity on Android
提问by Casebash
Is it possible to start an activity on the stack, clearing the entire history before it?
是否可以在堆栈上启动一个活动,在它之前清除整个历史记录?
The situation
情况
I have an activity stack that either goes A->B->C or B->C (screen A selects the users token, but many users only have a single token).
我有一个活动堆栈,要么是 A->B->C 要么是 B->C(屏幕 A 选择用户令牌,但许多用户只有一个令牌)。
In screen C the user maytake an action which makes screen B invalid, so the application wants to take them to screen A, regardless of whether it is already in the stack. Screen A should then be the only item on the stack in my application.
在屏幕 C 中,用户可能会采取使屏幕 B 无效的操作,因此应用程序希望将它们带到屏幕 A,无论它是否已经在堆栈中。屏幕 A 应该是我的应用程序中堆栈上的唯一项目。
Notes
笔记
There are many other similar questions, but I haven't found anything that answers this exact question. I tried calling getParent().finish()
- this always results in a null pointer exception. FLAG_ACTIVITY_CLEAR_TOP
only works if the activity is already on the stack.
还有许多其他类似的问题,但我没有找到任何可以回答这个确切问题的内容。我尝试调用getParent().finish()
- 这总是导致空指针异常。FLAG_ACTIVITY_CLEAR_TOP
仅当活动已经在堆栈中时才有效。
回答by Akos Cz
In API level 11 a new Intent Flag was added just for this: Intent.FLAG_ACTIVITY_CLEAR_TASK
在 API 级别 11 中,为此添加了一个新的意图标志:Intent.FLAG_ACTIVITY_CLEAR_TASK
Just to clarify, use this:
只是为了澄清,使用这个:
Java
爪哇
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
Kotlin
科特林
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
Unfortunately for API lvl <= 10, I haven't yet found a clean solution to this. The "DontHackAndroidLikeThis" solutionis indeed pure hackery. You should not do that. :)
不幸的是,对于 API lvl <= 10,我还没有找到一个干净的解决方案。该“DontHackAndroidLikeThis”的解决方案确实是纯粹的两轮牛车。你不应该那样做。:)
Edit:As per @Ben Pearson's comment, for API <=10 now one can use IntentCompatclass for the same. One can use IntentCompat.FLAG_ACTIVITY_CLEAR_TASK
flag to clear task. So you can support pre API level 11 as well.
编辑:根据@ Ben Pearson的评论,对于 API <=10 现在可以使用IntentCompat类。可以使用IntentCompat.FLAG_ACTIVITY_CLEAR_TASK
标志来清除任务。因此,您也可以支持 API 级别 11 之前的版本。
回答by monish george
Case 1:Only two activity A and B:
案例 1:只有两个活动 A 和 B:
Here Activity flow is A->B .On clicking backbutton from B we need to close the application then while starting Activity B from A just call finish() this will prevent android from storing Activity A in to the Backstack.eg for activity A is Loding/Splash screen of application.
这里的活动流程是 A->B。点击 B 的后退按钮,我们需要关闭应用程序,然后在从 A 启动活动 B 时只需调用完成()这将阻止 android 将活动 A 存储到 Backstack.eg 活动 A 是应用程序的加载/启动画面。
Intent newIntent = new Intent(A.this, B.class);
startActivity(newIntent);
finish();
Case 2:More than two activitiy:
案例2:两个以上的活动:
If there is a flow like A->B->C->D->B and on clicking back button in Activity B while coming from Activity D.In that case we should use.
如果有像 A->B->C->D->B 这样的流程,并且在来自活动 D 的同时单击活动 B 中的后退按钮。在这种情况下,我们应该使用。
Intent newIntent = new Intent(D.this,B.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newIntent);
Here Activity B will be started from the backstack rather than a new instance because of Intent.FLAG_ACTIVITY_CLEAR_TOP and Intent.FLAG_ACTIVITY_NEW_TASK clears the stack and makes it the top one.So when we press back button the whole application will be terminated.
由于 Intent.FLAG_ACTIVITY_CLEAR_TOP 和 Intent.FLAG_ACTIVITY_NEW_TASK 清除堆栈并使其成为最顶部的,因此 Activity B 将从 backstack 而不是新实例启动。因此,当我们按下后退按钮时,整个应用程序将终止。
回答by karan
With Android's Newer Version >= API 16 use finishAffinity()
使用 Android 的较新版本 >= API 16 使用 finishAffinity()
approach is suitable for >= API 16.
方法适用于 >= API 16。
Intent mIntent = new Intent(mContext,MainActivity.class);
finishAffinity();
startActivity(mIntent);
- Its is same as starting new Activity, and clear all stack.
- OR Restart to MainActivity/FirstActivity.
- 它与启动新活动相同,并清除所有堆栈。
- 或重新启动到 MainActivity/FirstActivity。
回答by user2895402
I spent a few hours on this too ... and agree that FLAG_ACTIVITY_CLEAR_TOP sounds like what you'd want: clear the entire stack, except for the activity being launched, so the Back button exits the application. Yet as Mike Repass mentioned, FLAG_ACTIVITY_CLEAR_TOP only works when the activity you're launching is already in the stack; when the activity's not there, the flag doesn't do anything.
我也花了几个小时...并同意 FLAG_ACTIVITY_CLEAR_TOP 听起来像你想要的:清除整个堆栈,除了正在启动的活动,所以后退按钮退出应用程序。然而正如 Mike Repass 提到的,FLAG_ACTIVITY_CLEAR_TOP 仅在您启动的活动已经在堆栈中时才有效;当活动不存在时,标志不会做任何事情。
What to do? Put the activity being launching in the stack with FLAG_ACTIVITY_NEW_TASK, which makes that activity the start of a new task on the history stack. Then add the FLAG_ACTIVITY_CLEAR_TOP flag.
该怎么办?将正在启动的活动与 FLAG_ACTIVITY_NEW_TASK 放在堆栈中,这使该活动成为历史堆栈上新任务的开始。然后添加 FLAG_ACTIVITY_CLEAR_TOP 标志。
Now, when FLAG_ACTIVITY_CLEAR_TOP goes to find the new activity in the stack, it'll be there and be pulled up before everything else is cleared.
现在,当 FLAG_ACTIVITY_CLEAR_TOP 去寻找堆栈中的新活动时,它会在那里并在其他所有内容被清除之前被拉起。
Here's my logout function; the View parameter is the button to which the function's attached.
这是我的注销功能;View 参数是函数附加到的按钮。
public void onLogoutClick(final View view) {
Intent i = new Intent(this, Splash.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
finish();
}
回答by Macarse
You shouldn't change the stack. Android back button should work as in a web browser.
你不应该改变堆栈。Android 后退按钮应该像在网络浏览器中一样工作。
I can think of a way to do it, but it's quite a hack.
我可以想出一种方法来做到这一点,但这是一个相当大的黑客。
Make your Activities
singleTask
by adding it to theAndroidManifest
Example:<activity android:name=".activities.A" android:label="@string/A_title" android:launchMode="singleTask"/> <activity android:name=".activities.B" android:label="@string/B_title" android:launchMode="singleTask"/>
Extend
Application
which will hold the logic of where to go.
singleTask
通过将其添加到AndroidManifest
示例中来制作您的活动:<activity android:name=".activities.A" android:label="@string/A_title" android:launchMode="singleTask"/> <activity android:name=".activities.B" android:label="@string/B_title" android:launchMode="singleTask"/>
扩展
Application
将保存去哪里的逻辑。
Example:
例子:
public class DontHackAndroidLikeThis extends Application {
private Stack<Activity> classes = new Stack<Activity>();
public Activity getBackActivity() {
return classes.pop();
}
public void addBackActivity(Activity activity) {
classes.push(activity);
}
}
From A to B:
从 A 到 B:
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(A.class);
startActivity(this, B.class);
From B to C:
从 B 到 C:
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(B.class);
startActivity(this, C.class);
In C:
在 C 中:
If ( shouldNotGoBackToB() ) {
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.pop();
}
and handle the back button to pop()
from the stack.
并pop()
从堆栈中处理后退按钮。
Once again, you shouldn't do this :)
再一次,你不应该这样做:)
回答by Keith Maurino
Immediately after you start a new activity, using startActivity
, make sure you call finish()
so that the current activity is not stacked behind the new one.
在您开始一项新活动后,立即使用startActivity
,确保您调用finish()
以使当前活动不会堆叠在新活动之后。
回答by Mohammad
Try this:
尝试这个:
Intent logout_intent = new Intent(DashboardActivity.this, LoginActivity.class);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(logout_intent);
finish();
回答by Gibolt
Advanced Reuseable Kotlin:
高级可重用 Kotlin:
You can set the flag directly using setter method. In Kotlin or
is the replacementfor the Java bitwise or |
.
您可以使用 setter 方法直接设置标志。在科特林or
是更换为Java按位或|
。
intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK
If you plan to use this regularly, create an Intent extension function
如果你打算经常使用这个,创建一个 Intent 扩展函数
fun Intent.clearStack() {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
You can then directly call this function before starting the intent
然后你可以在开始意图之前直接调用这个函数
intent.clearStack()
If you need the option to add additional flags in other situations, add an optional param to the extension function.
如果您需要在其他情况下添加额外标志的选项,请向扩展函数添加一个可选参数。
fun Intent.clearStack(additionalFlags: Int = 0) {
flags = additionalFlags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
回答by Neeraj Gupta
Intent i = new Intent(MainPoliticalLogin.this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
回答by shashikant yadav
Try below code,
试试下面的代码,
Intent intent = new Intent(ManageProfileActivity.this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
Intent.FLAG_ACTIVITY_CLEAR_TASK|
Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);