情况
我有一个活动堆栈可以进入A-> B-> C或B-> C(屏幕A选择用户令牌,但是许多用户只有一个令牌)。
在屏幕C中,用户可以执行使屏幕B无效的操作,因此应用程序希望将其带到屏幕A,而不管其是否已经在堆栈中。屏幕A应该是应用程序中堆栈上的唯一项。题。我尝试调用
getParent().finish()
-这总是导致空指针异常。 FLAG_ACTIVITY_CLEAR_TOP
仅在活动已经在堆栈中时才起作用。 #1 楼
在API级别11中,仅为此添加了一个新的Intent标志:Intent.FLAG_ACTIVITY_CLEAR_TASK为了澄清起见,请使用以下代码: />很遗憾,对于lvl <= 10而言,我还没有找到一个干净的解决方案。
“ DontHackAndroidLikeThis”解决方案的确是纯粹的黑客手段。你不应该那样做。 :)
编辑:
根据@Ben Pearson的评论,对于API <= 10,现在可以使用IntentCompat类。可以使用
IntentCompat.FLAG_ACTIVITY_CLEAR_TASK
标志清除任务。因此,您也可以支持API之前的11级。#2 楼
情况1:只有两个活动A和B:这里的活动流是A-> B。从B单击后退按钮时,我们需要关闭应用程序,然后在从A启动活动B时调用finish()这将防止android将Activity A存储到Backstack中。例如,对于Activity A是应用程序的Loding / Splash屏幕。
如果有A-> B-> C-> D-> B之类的流程,并且在来自活动D的活动B中单击后退按钮,在这种情况下我们应该使用。由于Intent.FLAG_ACTIVITY_CLEAR_TOP和Intent.FLAG_ACTIVITY_NEW_TASK将清除堆栈并使其成为顶层堆栈。因此,我们按返回按钮,整个应用程序将被终止。
评论
这对我有用。我在所有活动中都添加了这些标志。在这些活动中,后退按钮可以完美地转到上一个活动,而在主活动中,具有Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);完();整个应用程序已关闭,仍在内存中,但未激活,如果您重新启动,则该应用程序将进入初始屏幕:)
–拉科
13年7月19日在10:50
这应该是最好的答案。如果有人对我有相同的情况:A-> B-> C-> D-> E->(B)从E-> B应该有一个结果:A-> B
– Shem Alexis Chavez
19 Jun 14'在10:06
#3 楼
对于Android的较新版本> = API 16,请使用finishAffinity()
方法适用于> = API16。
Intent mIntent = new Intent(mContext,MainActivity.class);
finishAffinity();
startActivity(mIntent);
它是与启动新活动相同,并清除所有堆栈。
或重新启动到MainActivity / FirstActivity。
评论
这样就成功了,这些标志对我来说在4.x.x上不起作用,而且效果很好!谢谢
–乔纳森·阿斯特(Jonathan Aste)
16-09-23在18:57
如果您的目标是完成下面的所有活动(包括当前活动)并在自己的任务中开始新的活动,那么这似乎是正确的答案。
– ToBe
18年4月11日在12:25
#4 楼
我也花了几个小时...并且同意FLAG_ACTIVITY_CLEAR_TOP听起来像您想要的:清除整个堆栈,除了要启动的活动以外,因此“返回”按钮退出应用程序。但是正如Mike Repass所述,FLAG_ACTIVITY_CLEAR_TOP仅在您要启动的活动已经在堆栈中时才起作用。当活动不存在时,标志不执行任何操作。该怎么办?使用FLAG_ACTIVITY_NEW_TASK将正在启动的活动放入堆栈中,这使该活动成为历史记录堆栈上新任务的开始。然后添加FLAG_ACTIVITY_CLEAR_TOP标志。
现在,当FLAG_ACTIVITY_CLEAR_TOP去查找堆栈中的新活动时,它将存在并被拉起,然后清除所有其他内容。 >这是我的登出功能; 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();
}
评论
您是说CLEAR_TASK而不是CLEAR_TOP?
–安德鲁(Andrew)
2014年8月19日在18:40
#5 楼
您不应该更改堆栈。 Android后退按钮应该像在Web浏览器中一样工作。 >通过添加到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
,它将保持去往逻辑。示例:
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);
}
}
从A到B:
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(A.class);
startActivity(this, B.class);
从B到C:
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(B.class);
startActivity(this, C.class);
在C:
If ( shouldNotGoBackToB() ) {
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.pop();
}
,然后将后退按钮从堆栈中移至
pop()
。再一次,您不应该这样做:)
评论
最后,我决定保留Stack不变,只是告诉用户他们当前的屏幕无效
– Casebash
10年8月16日在1:42
非常令人沮丧的是,android不允许我们已经以这种方式管理活动堆栈。我很想在未来的Android应用程序中使用此解决方案。
– Cephron
13年2月19日在16:14
为了明确为什么不应该使用它:这是创建内存泄漏的好方法。在某些时候,操作系统可能决定终止后台活动,但是由于应用程序采用了它们的实例,因此操作系统将无法从破坏的活动中释放剩余的RAM。
–维特·胡登科(Vit Khudenko)
13年11月12日在12:57
@Arhimed还有其他问题吗?可以通过仅保留弱引用来弥补内存泄漏。
– Navin
14-12-28 at 13:33
@Navin是的,使用弱引用可以避免泄漏,但是如果GC之后没有活动的Activity引用,则整个方法将无用。再次-不要这样做,这对于Android是错误的方法。
–维特·胡登科(Vit Khudenko)
2014-12-29 23:30
#6 楼
在开始新活动之后,立即使用startActivity
确保调用finish()
,以使当前活动不堆积在新活动之后。评论
+1不错的解决方案,可以防止在特定情况下仅将一项活动放到历史记录堆栈中。
– marsbear
2012年4月27日在9:38
如果您在堆栈中有多个活动,则该命令不起作用,完成将仅清除先前的活动,而不清除其他活动...。
– Necronet
2012年8月13日在12:20
#7 楼
试试这个: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();
#8 楼
高级可重复使用的Kotlin:您可以使用setter方法直接设置标志。在Kotlin中,
or
是Java按位或|
的替代。 > intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK
如果您需要在其他情况下添加其他标志的选项,则可以在启动意图之前直接调用此函数
,在扩展功能中添加一个可选参数。
fun Intent.clearStack() {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
#9 楼
尝试以下代码,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);
评论
如果正在使用像这样的活动,则再次更新api,但以前存在的所有statck都将被清除
– Harsha
18年11月30日在11:03
#10 楼
对我来说,上述方法都不起作用。只需执行此操作即可清除所有先前的活动:
finishAffinity() // if you are in fragment use activity.finishAffinity()
Intent intent = new Intent(this, DestActivity.class); // with all flags you want
startActivity(intent)
#11 楼
Intent i = new Intent(MainPoliticalLogin.this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
#12 楼
有时您的Android模拟器可能无法连接Eclipse DDMS工具,并要求adb手动启动。在这种情况下,可以使用命令提示符启动或停止adb。评论
有时您的Android模拟器可能无法连接Eclipse DDMS工具,并要求adb手动启动。在这种情况下,您可以使用命令提示符启动或停止adb。意图i =新意图(OldActivity.this,NewActivity.class); //设置新任务并清除标志i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)startActivity(i);
–RajeshkumarG
16-10-6在9:11
#13 楼
我发现太简单了,只需在AndroidManifest
中添加新元素即可,方法如下:评论
如果您在本活动中要求权限,则此方法可能会在Android 6.0+上引起问题。
–重要A
16-09-3在10:34
评论
只是为了澄清一下,请使用:intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
–user123321
2012年12月12日18:18
如果没有Intent.FLAG_ACTIVITY_NEW_TASK,该应用有时会在android 4上自行关闭
–max4ever
2012年10月12日15:00
IntentCompat现在也具有清除任务的标志,因此您可以支持API之前的11级-developer.android.com/reference/android/support/v4/content/…
–本·皮尔森
2013年12月12日在12:34
在API级别<10的设备上,IntentCompat.FLAG_ACTIVITY_CLEAR_TASK被忽略。developer.android.com/reference/android/support/v4/content/…
–大卫
2014年6月9日20:11在
IntentCompat的标志只是为了避免崩溃,而不执行@David所说的任何操作。
–员工
14年8月18日在8:44