Android:アクティビティスタックをクリアする


132

アプリケーションにいくつかのアクティビティがあります。流れは非常に複雑です。ログアウトアプリケーションをクリックすると、ログイン画面に移動し、ユーザーはキャンセルボタン(を呼び出すsystem.exit(0))で終了できます

ときに私出口やバックボタン、システムがスタックから活動を呼び出し:(私はログイン画面に到達したときにどのように私は呼び出し?スタック内のすべての活動をクリアすることができますfinish()ので、多くの活動があるので実用的ではないではありませんし、いくつかの活動は何時に閉じる必要がありますネイティブカメラ呼び出しアクティビティなど、アクティブです。

validateuser logoutuser = new validateuser();
logoutuser.logOut();
Intent loginscreen = new Intent(homepage.this, Login2.class);
(homepage.this).finish();
loginscreen.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(loginscreen);

1
、このリンクをチェックし... stackoverflow.com/questions/5139686/exit-an-android-app/...
xydev

回答:


339

あなたのほとんどは間違っています。何があるかに関係なく既存のアクティビティスタックを閉じて新しいルートを作成する場合、正しいフラグのセットは次のとおりです。

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

ドキュメントから

public static final int FLAG_ACTIVITY_CLEAR_TASK
APIレベル11で追加

に渡されるインテントに設定されている場合 Context.startActivity()、このフラグは、アクティビティに関連付けられる既存のタスクを、アクティビティが開始される前にクリアします。つまり、アクティビティは空のタスクの新しいルートになり、古いアクティビティはすべて終了します。これは、と組み合わせてのみ使用できFLAG_ACTIVITY_NEW_TASKます。


完璧に働きました。ありがとう。奇妙なことに、minSDK = 9でエラーが発生しませんでした。
Mahm00d 2014

率直に言って、私はこの機能を使用したことはなく、クラッシュ後の復活などを行い、クラッシュの原因となった問題の修正に集中しました)
Cynichniy Bandera

同じ機能IntentCompat.makeRestartActivityTaskがサポートライブラリからも提供されます。
sealskej 2016

これらの2つのフラグのみを追加すると、アクティビティスタックトラックが後になり(前のフラグの上から開始)、次にアプリケーションを再起動して完全に終了するIntent.FLAG_ACTIVITY_CLEAR_TOPが追加されます。明示的にアクティビティにフラグを追加していません。何が問題でしょうか?
ファリッド

1
最良の始まりの1つ:「あなたのほとんどは間違っています。」
nibbana

31

startActivity最後のアクティビティを呼び出すと、いつでも使用できます

Intent.FLAG_ACTIVITY_CLEAR_TOP

その意図の旗として。

フラグの詳細については、こちらをご覧ください


それも役に立ちません。私は、datがfinish()で終わっていないアクティビティを表示するだけです。:(
ジェイ・マユ

FLAG_ACTIVITY_CLEAR_TOPは上部のアクティビティをクリアすると思います。私の問題は底の活動です:(
ジェイ・マユ

それは実際の流れに依存すると思います。詳しくdeveloper.android.com
David Olsson

7
正しいリソースをご提示いただきありがとうございます。私が犯した間違いは、ログインアクティビティを閉じることでした。閉じないでください。アクティビティが最初に読み込まれたとき。そのため、Clear_topフラグを使用してコールバックすると、ログインアクティビティによって上部のすべてのアクティビティがクリアされます。ログインは最初のentraceアクティビティなので、それ以降に開始されたすべてのアクティビティをクリアします。ビンゴはうまくいきました:)
ジェイ・マユ

13
ドキュメントから、FLAG_ACTIVITY_CLEAR_TOP は、特定のアクティビティが「現在のタスクで既に実行されている」場合のみスタックをクリアします
AlikElzin-kilaka

16

APIレベル4から現在のバージョン17まで機能する新しいトップアクティビティとして新しいアクティビティを開始するための簡単なヘルパーメソッドを次に示します。

static void startNewMainActivity(Activity currentActivity, Class<? extends Activity> newTopActivityClass) {
    Intent intent = new Intent(currentActivity, newTopActivityClass);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        intent.addFlags(0x8000); // equal to Intent.FLAG_ACTIVITY_CLEAR_TASK which is only available from API level 11
    currentActivity.startActivity(intent);
}

現在のアクティビティから次のように呼び出します:

startNewMainActivity(this, MainActivity.class);

1
常にintent.addFlags(0x8000);を使用することはできませんでした。それを簡素化しますか?
Davor 2013

このフラグはHoneycombで最初に導入されたので、以前のバージョンにどのような影響があるかはわかりません。それで、これは私が先住民であったことでした。しかし、私は条件付きの除去が問題になるべきではないと思います。
2013

1
APIレベルが11未満のときにそのフラグを追加したい場合、Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMBそれ以外のintent.addFlags(0x8000);場合は追加する必要はありません
Straw Hat

私はユーザーに意図を介して次々と多くのアクティビティを行ってもらいます。スタック上のアクティビティが多すぎてアプリがクラッシュしないようにするために何かする必要がありますか?ありがとう!
Ruchir Baronia

9

以下のコードでActivity Backstateをクリアします。

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

できた


私はユーザーに意図を介して次々と多くのアクティビティを行ってもらいます。スタック上のアクティビティが多すぎてアプリがクラッシュしないようにするために何かする必要がありますか?ありがとう!
Ruchir Baronia

@RuchirBaronia、行く場合A-> B-> C-> D-> E-> F-> G-> H、今すぐH->私はコードを書いています。アプリにはバックステートアクティビティがないため、アプリは終了します。これが役立つことを願っています。
Hiren Patel

それをする必要がありますか?アクティビティスタックをクリーンアップしないとどうなりますか?
Ruchir Baronia

@RuchirBaronia、バックプレス:H-> G-> F-> E-> D-> C-> B-> A
Hiren Patel

しかし、新しいアクティビティを呼び出すときに、白い画面が表示されることがあります。これを解決する方法は?
Sagar

4

私の場合、LoginActivityも閉じられました。結果として、

Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK

助けにはならなかった。

ただし、設定

Intent.FLAG_ACTIVITY_NEW_TASK

助けて頂きました。


私はユーザーに意図を介して次々と多くのアクティビティを行ってもらいます。スタック上のアクティビティが多すぎてアプリがクラッシュしないようにするために何かする必要がありますか?ありがとう!
Ruchir Baronia

3
Intent intent = new Intent(LoginActivity.this, Home.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  //It is use to finish current activity
startActivity(intent);
this.finish();

1
なぜ両方this.finish()を使用し、 setFlags()現在のアクティビティをクリアするのですか?
Sagar

3

に依存しない解決策を求めたとのことですが、finish()それでも解決できるのではないでしょうか。

終了フラグが静的クラス変数で発生するかどうかを追跡しました。静的クラス変数は、アプリの存続期間全体で存続します。各関連アクティビティonResume()ので、

@Override
public void onResume() {
    super.onResume();
    if (ExitHelper.isExitFlagRaised) {
        this.finish();
    }
}

ExitHelperクラス

public class ExitHelper {
    public static boolean isExitFlagRaised = false;
}

mainActivityで、ユーザーがボタンを押して終了するとしましょう-設定ExitHelper.isExitFlagRaised = true;してからfinish()。その後、自動的に再開される他の関連アクティビティも終了します。


MainActivity onresume()のコードを使用し、backpressの2番目のアクティビティからmainactivityに戻った場合
Mithu

3

この決定はうまくいきます:

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

しかし、新しいアクティビティが長く起動し、しばらくすると白い画面が表示されます。これが重要な場合は、次の回避策を使用してください。

public class BaseActivity extends AppCompatActivity {

    private static final String ACTION_FINISH = "action_finish";

    private BroadcastReceiver finisBroadcastReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        registerReceiver(finisBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                finish();
            }
        }, new IntentFilter(ACTION_FINISH));
    }

    public void clearBackStack() {
        sendBroadcast(new Intent(ACTION_FINISH));
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(finisBroadcastReceiver);
        super.onDestroy();
    }
}

使い方:

public class ActivityA extends BaseActivity {

    // Click any button
    public void startActivityB() {
        startActivity(new Intent(this, ActivityB.class));
        clearBackStack();
    }
}

欠点:スタックで閉じる必要があるすべてのアクティビティはBaseActivityを拡張する必要があります


2

Xamarin開発者は、以下を使用できます。

intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);

1

Kotlinの使用:

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

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

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

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

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

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