代码之家  ›  专栏  ›  技术社区  ›  Casebash

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

  •  296
  • Casebash  · 技术社区  · 15 年前

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

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

    在屏幕C中,用户

    笔记

    getParent().finish() -这总是导致空指针异常。 FLAG_ACTIVITY_CLEAR_TOP

    11 回复  |  直到 11 年前
        1
  •  695
  •   Community Mohan Dere    5 年前

    在API级别11中,仅为此添加了一个新的意图标志: Intent.FLAG_ACTIVITY_CLEAR_TASK

    只是想澄清一下,用这个:

    Java

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

    intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
    

    不幸的是,对于API级别<=我还没有找到一个干净的解决办法。 这个 "DontHackAndroidLikeThis" solution

    编辑: 根据@ Ben Pearson 的评论,用于API<=10现在可以使用 IntentCompat 同样的课程。可以使用 IntentCompat.FLAG_ACTIVITY_CLEAR_TASK 清除任务的标志。因此,您也可以支持API 11级之前的版本。

        2
  •  52
  •   monish george    12 年前

    案例1:只有两个活动A和B:

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

    案例2:两个以上的活动:

    Intent newIntent = new Intent(D.this,B.class);
    newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
    newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(newIntent);
    

        3
  •  45
  •   karan Max Martyniuk    9 年前

    使用Android的较新版本>=API 16使用 finishAffinity()

    方法适用于>=API 16。

    Intent mIntent = new Intent(mContext,MainActivity.class);
    finishAffinity();
    startActivity(mIntent);
    
    • 它与启动新活动相同,并清除所有堆栈。
    • 或重新启动到MainActivity/FirstActivity。
        4
  •  26
  •   user2895402    12 年前

    我也花了几个小时。。。并同意FLAG\u ACTIVITY\u CLEAR\u TOP听起来像您想要的:清除整个堆栈,除了正在启动的活动,这样Back按钮就退出了应用程序。然而,正如Mike Repass所提到的,FLAG\u ACTIVITY\u CLEAR\u TOP只在您启动的活动已经在堆栈中时起作用;当活动不在那里时,标志不起任何作用。

    怎么办?将正在启动的活动放入带有标志\u activity \u NEW \u TASK的堆栈中,这使该活动成为历史堆栈上新任务的开始。然后添加标志\u ACTIVITY\u CLEAR\u TOP标志。

    现在,当FLAG\u ACTIVITY\u CLEAR\u 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();
    }
    
        5
  •  13
  •   Shankar Agarwal    13 年前

    • 让你的活动 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);
    

    If ( shouldNotGoBackToB() ) {
      DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
      app.pop();
    }
    

    然后按“后退”按钮 pop()

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

        6
  •  12
  •   Keith Maurino    13 年前

    开始新活动后,立即使用 startActivity finish() 以便当前活动不会堆积在新活动之后。

        7
  •  6
  •   Gibolt    6 年前

    可以使用setter方法直接设置标志。在科特林 or replacement | .

    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
    }
    

    然后可以在启动intent之前直接调用此函数

    intent.clearStack()
    

    fun Intent.clearStack(additionalFlags: Int = 0) {
        flags = additionalFlags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
    }
    
        8
  •  5
  •   Pang Ajmal PraveeN    8 年前

    试试这个:

    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();
    
        9
  •  4
  •   Sagar Zala    7 年前

    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);
    
        10
  •  3
  •   Amir Hossein Ghasemi    6 年前

    为了我 没有人 不起作用。

    就这样对我 清除所有以前的活动

    finishAffinity() // if you are in fragment use activity.finishAffinity()
    Intent intent = new Intent(this, DestActivity.class); // with all flags you want
    startActivity(intent)
    
        11
  •  2
  •   Joaquin Iurchuk    7 年前
    Intent i = new Intent(MainPoliticalLogin.this, MainActivity.class);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    startActivity(i);
    
        12
  •  -1
  •   RajeshkumarG    9 年前

    有时您的android仿真器可能无法连接eclipseddms工具并请求adb手动启动。在这种情况下,可以使用命令提示符启动或停止adb。

        13
  •  -2
  •   Tauseef    9 年前

    我发现太简单的黑客只是做这个添加新元素 AndroidManifest 作为:-

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

    这个 android:noHistory 将清除堆栈中不需要的活动。