web-dev-qa-db-ja.com

Intent.FLAG_ACTIVITY_CLEAR_TOPを使用してアクティビティスタックをクリアするにはどうすればよいですか?

私はこれを使用することに関するいくつかの投稿を読みましたが、それは私のために機能していないため、何かを見逃しているに違いありません。私のアクティビティAのマニフェストにはlaunchmode = "singleTop"があります。 launchmode = "singleInstance"でアクティビティBを開始します。アクティビティBはブラウザを開き、受信して意図を返します。これがsingleInstanceである理由です。ユーザーがアクティビティAに戻され、アクティビティBに戻るのではなく、戻るボタンを押してアクティビティを終了できるように、戻るボタンをオーバーライドしようとしています。

// activity B
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
 if (Android.os.Build.VERSION.SDK_INT < Android.os.Build.VERSION_CODES.Eclair
  && keyCode == KeyEvent.KEYCODE_BACK
  && event.getRepeatCount() == 0) onBackPressed();
 return super.onKeyDown(keyCode, event);
}
@Override
public void onBackPressed() {
 startActivity(new Intent(this, UI.class)
 .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
 return;
}

ブラウザから戻った後、スタックは... A、B、Browser、B

このコードは、スタックを...に変更することを期待します。A...もう一度押すと、ユーザーはホーム画面に戻ります。

代わりに、スタックを... A、B、Browser、B、Aに変更するようです...これらのフラグが存在しないかのように。

StartActivityの後にアクティビティBでfinish()を呼び出そうとしましたが、[戻る]ボタンを押すと再びブラウザに戻ります!

私は何が欠けていますか?ありがとうございました!

75
piusvelte

@bitestarには正しい解決策がありますが、もう1つのステップがあります。

ドキュメントには隠されていましたが、launchModeActivitystandard以外に変更する必要があります。それ以外の場合は、最上部にリセットされるのではなく、破棄されて再作成されます。

64
ScouseChris

アクティビティA-> B-> C-> Dを開始しました。アクティビティDIで戻るボタンが押されたとき、アクティビティAに移動します。Aが私の開始点であり、したがってすでにスタックにあるため、Aの上のすべてのアクティビティがクリアされ、Aから他のアクティビティに戻ることはできません。

これは実際に私のコードで動作します:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        Intent a = new Intent(this,A.class);
        a.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(a);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}       
103

このために、Intentを開始するためにFLAG_ACTIVITY_CLEAR_TOPフラグを使用します
FLAG_ACTIVITY_NEW_TASKなし)

launchMode = "singleTask"起動されたアクティビティのマニフェスト内。

必要に応じて動作するようです-アクティビティは再起動せず、他のすべてのアクティビティは閉じられます。

19
Fedir Tsapana

この質問にはすでに十分な答えがありますが、誰かがこのフラグがこの独特の方法で機能する理由を知りたいと思うと思いました、これは私が見つけたものです Android documentation

上記の例で現在実行中のアクティビティBのインスタンスは、onNewIntent()メソッドでここから開始する新しいインテントを受け取るか、新しいインテントで終了して再起動します。

起動モードを「複数」(デフォルト)として宣言し、FLAG_ACTIVITY_SINGLE_TOPを同じインテントに設定していない場合、終了して再作成されます。他のすべての起動モードの場合、またはFLAG_ACTIVITY_SINGLE_TOPが設定されている場合、このインテントは現在のインスタンスのonNewIntent()に配信されます。


それで、どちらか、
1。アクティビティAのlaunchModeを標準から別のもの(つまり、singleTaskまたは何か)に変更します。フラグFLAG_ACTIVITY_CLEAR_TOPはアクティビティAを再起動しません。

または、

2Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOPをフラグとして使用します。その後、それはあなたが望む方法で動作します。

10
Darpan

3つのフラグを使用して問題を解決します。

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
                Intent.FLAG_ACTIVITY_CLEAR_TASK | 
                Intent.FLAG_ACTIVITY_NEW_TASK);
3
Houssin Boulla

既に受け入れられた答えがあることは知っていますが、FLAG_ACTIVITY_CLEAR_TOPが特定のケースで意味があるとは思わないため、OPでどのように機能するかわかりません。そのフラグは、同じタスクのアクティビティにのみ関連します。彼の説明に基づいて、各アクティビティは独自のタスクにあります:A、B、およびブラウザ。

おそらく彼を捨てているのは、AがsingleTaskであるはずのときに、AがsingleTopであるということです。 AがsingleTopで、BがAを開始すると、AはBのタスクにないため、新しいAが作成されます。 singleTopのドキュメントから:

「アクティビティのインスタンスが現在のタスクの最上部に既に存在する場合、システムはそのインスタンスにインテントをルーティングします...」

BはAを開始するため、現在のタスクはsingleInstanceのBのタスクであり、したがってAを含めることはできません。singleTaskを使用してそこに目的の結果を達成します。

最後に、BがAを開始し、ユーザーがAから押し戻した後、OPはBもブラウザも見たくない。これを実現するには、Bでfinish()を呼び出すのが正しいです。繰り返しますが、FLAG_ACTIVITY_CLEAR_TOPはAのタスク内の他のアクティビティを削除しません。これは、彼の他のアクティビティがすべて異なるタスクにあるためです。彼が行方不明になったのは、Bがブラウザのインテントを起動するときにFLAG_ACTIVITY_NO_HISTORYも使用する必要があるということです。 注: OPのアプリケーションを起動する前にブラウザーが既に実行されている場合、もちろんAから戻るときにブラウザーが表示されます。実際にこれをテストするには、アプリケーションを開始する前のブラウザ。

2
Kevin

マニフェストファイルにAndroid:noHistory = "true"を追加します。

<manifest >
        <activity
            Android:name="UI"
            Android:noHistory="true"/>

</manifest>
2
Ahmad Aghazadeh

新しいインテントを開始した後、activity_name.this.finish()を呼び出しましたが、うまくいきました。

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

しかし、それは私にはうまくいきません...私はこのソリューションを使用することを提案していませんが、フラグを設定してもうまくいかない場合は、これを試すことができます。しかし、まだ使用しないことをお勧めします

2

FLAG_ACTIVITY_NEW_TASKは、新しいタスクを開始する問題です。削除するだけで完了です。

まあ、私はあなたがそれらを扱う前にすべてのフラグが何をするかを読むことをお勧めします

読み取り thisIntent Flags here

1
100rabh

最初は、FLAG_ACTIVITY_CLEAR_TOPを機能させるのにも問題がありました。最終的には、その値(0x04000000)を使用して動作するようになりました。 Eclipse /コンパイラの問題があるように見えます。しかし、残念ながら、生き残った活動は再開されます。これは私が望んでいることではありません。簡単な解決策はないようです。

1
ja_chu