web-dev-qa-db-ja.com

履歴タスク全体をクリアしてAndroidで新しいアクティビティを開始する

スタック上でアクティビティを開始し、それ以前の履歴全体をクリアすることは可能ですか?

状況

A - > B - > CまたはB - > Cのいずれかになるアクティビティスタックがあります(画面Aでユーザートークンを選択しますが、多くのユーザーは単一のトークンしか持っていません)。

画面Cでは、ユーザーが画面Bを無効にするようなアクションをとることがあるので、アプリケーションはすでにスタックにあるかどうかに関係なく、画面Aに移動します。その場合、画面Aが私のアプリケーションのスタック上の唯一の項目になるはずです。

他にも似たような質問がたくさんありますが、この質問に答えるものは見つかりませんでした。私はgetParent().finish()を呼び出そうとしました - これは常にnullポインタ例外を引き起こします。 FLAG_ACTIVITY_CLEAR_TOPは、アクティビティがすでにスタック上にある場合にのみ機能します。

303
Casebash

APIレベル11では、このために新しいインテントフラグが追加されました。 Intent.FLAG_ACTIVITY_CLEAR_TASK

わかりやすくするために、これを使用してください。

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

残念ながら、API lvl <= 10の場合、これに対するきれいな解決策はまだ見つかっていません。 "DontHackAndroidLikeThis"ソリューション は確かに純粋なハッカーです。あなたはそうするべきではありません。 :)

編集:@ Ben Pearson のコメントによると、API <= 10の場合は今すぐ使用できます IntentCompat) 同じクラス。タスクをクリアするためにIntentCompat.FLAG_ACTIVITY_CLEAR_TASKフラグを使うことができます。そのため、APIレベル11以前もサポートできます。

601
Akos Cz

ケース1:2つの活動AとBのみ

ここではアクティビティフローはA-> Bです。Bから戻るボタンをクリックするとアプリケーションを閉じる必要があります。AからアクティビティBを開始するときにfinish()を呼び出すだけで、AndroidはアクティビティAをアクティビティAのBackstack.egに保存できなくなります。アプリケーションのコーディング/スプラッシュスクリーン。

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

ケース2:2つ以上の活動:

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

Intent.FLAG_ACTIVITY_CLEAR_TOPとIntent.FLAG_ACTIVITY_NEW_TASKのため、ここではアクティビティBは新しいインスタンスではなくバックスタックから開始されます。スタックをクリアして一番上のスタックにします。ボタンを押すとアプリケーション全体が終了します。

46
monish george

Androidの新しいバージョン> = API 16ではfinishAffinity()を使用

アプローチは> = API 16に適しています。

Intent mIntent = new Intent(mContext,MainActivity.class);
finishAffinity();
startActivity(mIntent);
  • それは新しいアクティビティを開始することと同じで、すべてのスタックをクリアします。
  • またはMainActivity/FirstActivityに再起動します。
33
karan

私もこれに数時間を費やしました…そして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();
}
21
user2895402

あなたはスタックを変えるべきではありません。 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()へ戻るボタンを操作してください。

もう一度、あなたはこれをするべきではありません:)

12
Macarse

startActivityを使用して新しいアクティビティを開始した直後は、現在のアクティビティが新しいアクティビティの後ろに重ならないように、必ずfinish()を呼び出してください。

11
Keith Maurino

これを試して:

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();
4
Mohammad
Intent i = new Intent(MainPoliticalLogin.this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
1
Neeraj Gupta

以下のコードを試してください、

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

私にとってはなし上記の方法の--- 動作しません。

これを以前のすべてのアクティビティをクリアする:にするだけです。

finishAffinity() // if you are in fragment use activity.finishAffinity()
Intent intent = new Intent(this, DestActivity.class); // with all flags you want
startActivity(intent)