Android:バックスタックから以前のすべてのアクティビティを削除します


119

プロファイルアクティビティの[ ログアウト ]ボタンをクリックしているときに、ユーザーをログインページに移動します。このページでは、新しい資格情報を使用する必要があります。

したがって、私はこのコードを使用しました:

Intent intent = new Intent(ProfileActivity.this,
        LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

onButtonClickログアウトボタンの。

しかし、問題は、ログインアクティビティのデバイスの戻るボタンをクリックすると、ProfileActivityに移動することです。LoginActivityでデバイスの戻るボタンを押すと、アプリケーションが閉じるはずだと思っていました。

何が悪いのですか?

LoginActivityのandroid:launchMode="singleTop"マニフェストにも追加しました

ありがとうございました


@GauravVashisth私は、このソリューションの次ましたstackoverflow.com/questions/5794506/...
Archie.bpgc

@ abbas.aniefaそのソリューションは少し複雑です。それがすべてのバックスタックをクリアする唯一の方法です。30以上のアクティビティがあるので、すべてのブロードキャストコードを作成する必要があります
Archie.bpgc '18 / 10/18

これを試してみてください、stackoverflow.com / questions / 10961481 /…。ブロードキャストの使用は、より優れたソリューションです。
abbas.aniefa

ログアウトに使用できる別のアプローチです。ログアウトして1つのフラグをsharedpreferencesに保存し、アクティビティの各onRestart()メソッドでこの変数の値をチェックして、trueに設定すると、現在のアクティビティを終了できます。したがって、バックグラウンドで開いているアクティビティの数に関係なく。これですべてのアクティビティが終了します。
Hiren Dabhi

元のコードは、実際にはAPIレベル11以上で調整することで機能します。あなただけの単一の呼び出しで一緒に旗を置く必要があります。intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);私はこの質問から答えを得た:stackoverflow.com/questions/3473168/...
jokeefe

回答:


302

ここで提案され解決策は私にとってうまくいきました:

ジャワ

Intent i = new Intent(OldActivity.this, NewActivity.class);
// set the new task and clear flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);

コトリン

val i = Intent(this, NewActivity::class.java)
// set the new task and clear flags
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(i)

ただし、APIレベル> = 11が必要です。


皆さん、のドキュメントを読んでくださいFLAG_ACTIVITY_CLEAR_TASK。これが公式な方法です。アプリ内のすべてのアクティビティを変更する必要はありません。
AlikElzin-kilaka 2015

これは、通知のために動作しませんstackoverflow.com/questions/24873131/...
サム・

私は私のminAPI = 16を持っているので、これは私にとって完全にうまく機能しています。ただし、APIが21を超えるとビューの実行が少し遅くなり、APIが21を下回るとスムーズになることに気付きました。同じ問題が発生している人はいますか?
Red M

1
これは、活動のための新しいタスクを作成します
のRohit

@kgiannakakisタスクが1つ(アクティビティバックスタック)しかない場合は間違いなくソリューションが機能しますが、複数のタスク(アクティビティスタック)がある場合は機能しません。たとえば、アプリケーションA、B、C、Dに4つのアクティビティがあるとします。2つのアクティビティバックスタックA-> B-> C(background)とD-> A-> B(Foreground)があり、If I現在のスタック(D-> A-> B)からアクティビティAを呼び出し、インテントフィルターを使用して何が起こるかを提案しました。これにより、現在のスタック(D-> A-> B)がクリアされ、アクティビティAが開かれます。アプリケーションですが、最近のアプリボタンを押すと、アプリのバックスタックが2つ表示されます。
Rahul Pareta

31

ログアウトボタンを使用するときに、アプリケーションのすべてのアクティビティをクリアする1つの解決策を次に示します。

アクティビティを開始するたびに、次のように開始します。

Intent myIntent = new Intent(getBaseContext(), YourNewActivity.class);
startActivityForResult(myIntent, 0);

アプリ全体を閉じたい場合は、次のようにします。

setResult(RESULT_CLOSE_ALL);
finish();

RESULT_CLOSE_ALLは、すべてのアクティビティを閉じることを通知する一意の整数を持つ最終的なグローバル変数です。

次に、すべてのアクティビティのonActivityResult(...)コールバックを定義します。これにより、アクティビティがRESULT_CLOSE_ALL値で戻るときに、次の呼び出しも行われますfinish()

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch(resultCode)
    {
    case RESULT_CLOSE_ALL:
        setResult(RESULT_CLOSE_ALL);
        finish();
    }
    super.onActivityResult(requestCode, resultCode, data);
}

これにより、すべてのアクティビティを閉じるカスケード効果が発生します。

ただし、これはハックであり、使用startActivityForResultするように設計されていない方法で使用します。

おそらくこれを行うためのより良い方法は、次に示すようにブロードキャストレシーバーを使用することです。

ログアウト時にアクティビティ履歴スタックをクリアし、「戻る」ボタンがログイン済みのアクティビティのみを開かないようにする

他のメソッドについてもこれらのスレッドを参照してください。

Android:バックスタックをクリアする

以前のすべてのアクティビティを完了します


4
歴史に約30の活動があるとき、それは実現可能ですか?
Rakesh Gondaliya 2013年

4
する必要があります。ただし、履歴に30のアクティビティがある場合は、デザインの変更を検討することをお勧めします。30は少し多すぎるようで、Androidはそれ自体を殺してしまう可能性があります。
Anup Cowkur 2013年

1
これは悪いやり方のようです。@RakeshGondaliyaの回答の質問は正当なようです。30多分単に「高い」数の活動を表す数。よりよいこれは、回答ルックス:stackoverflow.com/a/3008684/243709
アマンアラム

この答えは素晴らしいです。EventBusライブラリを使用して、バックスタック内のアクティビティにイベントを送信することもできます。github.com/greenrobot/EventBus
スタン

シンプルな「Intent.FLAG_ACTIVITY_CLEAR_TOP」フラグを意図的に使用する方が良い
Naveen Rao

18

アクティビティスタックを完全にクリアするには、次のように、TaskStackBuilderを使用して新しいタスクスタックを作成します。

Intent loginIntent = LoginActivity.getIntent(context);
TaskStackBuilder.create(context).addNextIntentWithParentStack(loginIntent).startActivities();

これにより、新しいクリーンなタスクスタックが作成されるだけでなく、LoginActivityに親アクティビティがある場合に「上へ」ボタンが適切に機能するようになります。


1
これはそれを行うための最良の方法です。
Paul Burke、

FLAG_ACTIVITY_NEW_TASKまたはfinishAffinity()私のために働かなかった。この答えだけが目的を解決しました。
TM

[戻る]ボタンでアプリを終了し、アプリアイコンで戻る場合は、そのメソッドを呼び出したアクティビティで開きます。だから私のために働いていません。
Tgo1014 2018年

17

finishAffinity()API 16で追加されましたActivityCompat.finishAffinity()。以前のバージョンで使用します。インテントを使用してアクティビティを起動し、現在のアクティビティを終了するとき。ActivityCompat.finishAffinity()代わりに使用 してくださいfinish()。現在のアクティビティの下にあるすべてのスタックされたアクティビティを終了します。それは私にとってはうまくいきます。


3
それは実際ですActivityCompat.finishAffinity()
ベルガは

finishAffinity()また、同じアフィニティのバックスタックに存在するすべてのアクティビティで現在のアクティビティを終了します。
Neeraj Sewani、2018年

10

何がうまくいったか

Intent intent = new Intent(getApplicationContext(), HomeActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
startActivity(mainIntent);

5

私が提案できる解決策の1つはandroid:launchMode="singleTop"、私のProfileActivityのマニフェストに追加することです。ログアウトをクリックすると、LoginActivityを再開してログオフ できます ログアウト時にこれを呼び出すことができます。

Intent in = new Intent(Profile.this,Login.class);
                in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(in);
                finish();

私はこれを行いました、何が起こったのですか:[戻る]ボタンをクリックすると、ProfileActivityに来たところからActivtyに移動します
Archie.bpgc

これは、finish()を呼び出すのではなく、新しいインテントを呼び出すことによってProfileActivityに来たために発生する可能性があります。LoginActivty以外のアクティビティからProfileActivityにどのようにアクセスしていますか?
Android

私は同じ質問を越えています。ログインインテントがシステムによって破棄された場合、たとえばメモリが不足しているために機能しないと思います。
user1914692 2013

5

API 11以降では、次のIntent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASKように使用できます。

Intent intent = new Intent(this, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent);

以前のすべてのアクティビティを完全にクリアし、新しいアクティビティを開始します。


4

あなたは試すことができfinishAffinity()ます、それは現在のすべての活動を閉じ、Android 4.1以上で動作します


1
finishAffinity()がAPI 16で追加されました。以前のバージョンではActivityCompat.finishAffinity()を使用してください。私はうまくいきます。
Anurag Srivastava

2

私も同じ問題に直面しています。

ログインアクティビティで私がしていることは何ですか。

    Intent myIntent = new Intent(MainActivity.this, ActivityLoggedIn.class);
    finish();
    MainActivity.this.startActivity(myIntent);  

ログアウト時

   Intent myIntent = new Intent(ActivityLoggedIn.this, MainActivity.class);
   finish();
   ActivityLoggedIn.this.startActivity(myIntent);

これはうまく機能しますが、ActivityLoggedInでアプリを最小化し、アプリドロワーのランチャーボタンアイコンをクリックすると、MainActivityが再び起動します:-/フラグを使用しています

android:LaunchMode:singleTask 

MainActivityの場合。


2

以下を使用します activity

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);

フラグメントを使用するためにCLEAR_TASKフラグを削除します。

これが一部の人に役立つことを願っています。


1

そのままにして

Intent intent = new Intent(ProfileActivity.this,
    LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(intent);

4
動いていない。それでも、戻るボタンを使用してProfileActivityに移動できます
Archie.bpgc '18

1

どのインテントフラグも機能しませんでしたが、次の方法で修正しました。

ユーザーが1つのアクティビティからログアウトするとき、そのアクティビティからメッセージをブロードキャストする必要があり、それを閉じたいアクティビティで受信してから、finish()を呼び出します。そしてそれはかなりうまくいきます。


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

APIレベル11以上ではFLAG_ACTIVITY_CLEAR_TASKFLAG_ACTIVITY_NEW_TASKIntentを使用してフラグを付け、すべてのアクティビティスタックをクリアします。

Intent i = new Intent(OldActivity.this, NewActivity.class);
// set the new task and clear flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |  Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i);

0

これを使って

Intent i1=new Intent(getApplicationContext(),StartUp_Page.class);
i1.setAction(Intent.ACTION_MAIN);
i1.addCategory(Intent.CATEGORY_HOME);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i1);
finish();

あなたはsetFlagsとaddFlagsを知っていましたか?
GvSharma


0

高度で再利用可能なKotlin:

setterメソッドを使用してフラグを直接設定できます。Kotlinでorある代替のJavaビット単位のためか|

intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK

これを定期的に使用する場合は、Intent拡張関数を作成します

fun Intent.clearStack() {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

その後、インテントを開始する前にこの関数を直接呼び出すことができます

intent.clearStack()

他の状況でフラグを追加するオプションが必要な場合は、オプションのパラメーターを拡張関数に追加します。

fun Intent.clearStack(additionalFlags: Int = 0) {
    flags = additionalFlags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.