首页 文章

清除整个历史记录堆栈并在Android上启动新活动

提问于
浏览
285

是否可以在堆栈上启动活动,清除之前的整个历史记录?

The situation

我有一个活动堆栈,可以是A-> B-> C或B-> C(屏幕A选择用户令牌,但许多用户只有一个令牌) .

在屏幕C中,用户可以采取使屏幕B无效的动作,因此应用程序想要将它们带到屏幕A,而不管它是否已经在堆栈中 . 屏幕A应该是我的应用程序中堆栈上唯一的项目 .

Notes

还有许多其他类似的问题,但我没有发现任何可以回答这个问题的问题 . 我试着调用 getParent().finish() - 这总是会导致空指针异常 . FLAG_ACTIVITY_CLEAR_TOP 仅在活动已在堆栈中时才有效 .

11 回答

  • 12

    我发现太简单的黑客只是在 AndroidManifest 中添加新元素: -

    <activity android:name=".activityName"
              android:label="@string/app_name"
              android:noHistory="true"/>
    

    android:noHistory 将清除Stack中不需要的活动 .

  • 567

    有时您的Android模拟器可能无法连接eclipse DDMS工具并要求adb手动启动 . 在这种情况下,您可以使用命令提示符启动或停止adb .

  • 10

    Case 1:Only two activity A and B:

    这里的活动流程是A-> B.点击B的后退按钮我们需要关闭应用程序然后从A启动活动B只需调用finish()这将阻止android将活动A存储到Backstack.eg中,活动A是Loding / Splash应用程序屏幕 .

    Intent newIntent = new Intent(A.this, B.class);
    startActivity(newIntent);
    finish();
    

    Case 2:More than two activitiy:

    如果有来自活动D的A-> B-> C-> D-> B之类的流和活动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);
    

    这里活动B将从backstack而不是新实例启动,因为Intent.FLAG_ACTIVITY_CLEAR_TOP和Intent.FLAG_ACTIVITY_NEW_TASK清除堆栈并使其成为最重要的一个 . 所以当我们按下后退按钮时,整个应用程序将被终止 .

  • 4

    在API级别11中,为此添加了新的Intent Flag:Intent.FLAG_ACTIVITY_CLEAR_TASK

    只是为了澄清,使用这个:

    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    

    不幸的是,对于API lvl <= 10,我还没有找到一个干净的解决方案 . "DontHackAndroidLikeThis" solution确实是纯粹的hackery . 你不应该这样做 . :)

    Edit: 根据@ Ben Pearson的评论,对于API <= 10,现在可以使用IntentCompat类 . 可以使用 IntentCompat.FLAG_ACTIVITY_CLEAR_TASK 标志来清除任务 . 因此,您也可以支持API级别11 .

  • 43
    Intent i = new Intent(MainPoliticalLogin.this, MainActivity.class);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    startActivity(i);
    
  • 1

    With Android's Newer Version >= API 16 use finishAffinity()

    approach is suitable for >= API 16.

    Intent mIntent = new Intent(mContext,MainActivity.class);
    finishAffinity();
    startActivity(mIntent);
    
    • 它与启动新Activity相同,并清除所有堆栈 .

    • 或重新启动到MainActivity / FirstActivity .

  • 19

    我也花了几个小时...并同意FLAG_ACTIVITY_CLEAR_TOP听起来像你想要的:清除整个堆栈,除了正在启动的活动,所以Back按钮退出应用程序 . 然而正如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();
    }
    
  • 27

    你不应该改变堆栈 . 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() .

    再一次,你不应该这样做:)

  • 0

    试试下面的代码,

    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);
    
  • -1

    试试这个:

    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();
    
  • -1

    使用 startActivity 开始新活动后,请确保调用 finish() ,以便当前活动不会堆叠在新活动后面 .

相关问题