情况

我有一个活动堆栈可以进入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级。

评论


只是为了澄清一下,请使用: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

#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