Intent.FLAG_ACTIVITY_CLEAR_TOPをどのように使用してアクティビティスタックをクリアしますか?


84

私はこれの使用についていくつかの投稿を読みましたが、それが私のために機能していないので何かが欠けているに違いありません。私のアクティビティAのマニフェストにはlaunchmode = "singleTop"があります。アクティビティBをlaunchmode = "singleInstance"で開始します。アクティビティ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()を呼び出そうとしましたが、戻るボタンを押すと再びブラウザに戻ります。

何が足りないのですか?ありがとうございました!

回答:


72

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

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


51
実際には...Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOPまさにそれを行います。
–derk- 2013

その例については、Steel_fedexのソリューションを確認してください。
ダーパン2014年

2
では、Steel_fedexのソリューションはどこにあるのでしょうか。
ChangWon Jeong Juicycool

112

アクティビティ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);
}       

4
このソリューションは、すべての仲介活動を終了します。また、RootActivityを再起動します。以下の@Steel_Fedexのソリューションを確認できます。同じことをしますが、RootActivityを再起動しません。
ダーパン2014年

これが私の場合の最良の解決策です。私は実際にルートアクティビティを再開したい
Tash Pemhiwa 2016年

24

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

そして、launchMode = "singleTask"立ち上げ活動のマニフェストインチ

必要に応じて機能しているようです。アクティビティは再開されず、他のすべてのアクティビティは閉じられます。


確認したところ、Bitsterのソリューションが機能しません。このソリューションが機能している間。RootActivityが再起動しませんでした。
ダーパン2014年

より賢くあなたの言葉を選んでください。Bitestarソリューションは実際に機能します!
Jesper Bischoff-Jensen 2014

singleTaskは私のために機能するので、Activityは再作成せず、onNewIntentでイベントを処理します。
Jishi Chen

11

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

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

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


だから、どちらか、
1。変更launchMode(すなわち。標準から何か他のものへの活動AのsingleTaskか何か)。その後、フラグFLAG_ACTIVITY_CLEAR_TOPはアクティビティAを再開しません。

または、

2Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOPあなたの旗として使用してください。その後、それはあなたが望むように動作します。


8

問題を解決するために3つのフラグを使用します。

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

4

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

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

</manifest>

初めてこのフラグを参照してください、それは私の場合のために働いていた、ありがとう
vlasentiy

3

私はactivity_name.this.finish()新しい意図を始めた後に電話をしました、そしてそれは私のために働きました。

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

しかし、それは私にはうまくいきません...私はこの解決策を使用することを提案していませんが、フラグを設定してもうまくいかない場合は、これを試すことができます..それでも私はそれを使用しないことをお勧めします


2

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

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

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

BがAを開始するため、現在のタスクはBのタスクです。これはsingleInstance用であり、したがってAを含めることはできません。システムがAを持つタスクを見つけてそのタスクをフォアグラウンドに移動するため、singleTaskを使用して目的の結果を達成します。

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


1

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

フラグを操作する前に、すべてのフラグが何をするかを読むことをお勧めします

これインテントフラグをここで読む


1
私は旗を読みました、そしてそれは私が必要としたもののように聞こえました。とにかく、FLAG_ACTIVITY_NEW_TASKを削除しても結果には影響しません。それはまだ無限の戻るボタンループです... A-> B、Aに戻る、Bに戻る、Aに戻る...
piusvelte 2010

?FLAG_ACTIVITY_NEW_TASKがintent.Checkのにあったかのようにあなたは必ず、なぜあなたはsingleInstanceとしてBを使用しているされているAA「singleInstance」アクティビティは働きdeveloper.android.com/guide/topics/fundamentals.html
100rabh

Bは、ブラウザからコールバックされたインテントを受信する必要があります。起動モードをsingleTaskに変更しようとしましたが、それでも機能しますが、戻るボタンのループが発生します。
piusvelte 2010

そこでFLAG_ACTIVITY_NEW_TASKを使用したため、機能しなかったと思います。FLAG_ACTIVITY_CLEAR_TOPのみを使用し、singleTaskもsingleInstanceも使用しない方がよい
100rabh 2010

1
Intent.FLAG_ACTIVITY_SINGLE_TOP再作成を防ぐために追加すれば、それは実用的な解決策になるはずだと思います
yonojoy 2014年

1

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

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