読者です 読者をやめる 読者になる 読者になる

Finish this activity, and tries to finish all activities immediately below it in the current task that have the same affinity

f:id:misyobun:20170217014653j:plain

Androidアプリを開発している人から「新しい画面に遷移したら、それまでの全てのActivityを消したいんだけど、どうやるのかな?」という質問があった。 どうやら画面遷移時に下記のコードを試してみたところ、期待していた動作が得られなかったとのことだ。

Intent intent = new Intent(getApplicationContext(), NextActivity.class);  

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

startActivity(intent);  

確かにインターネット上で同様のIntentのFlag指定コードを「画面遷移時にActivityをクリアする時の常套手段」として紹介する記事を良く見る。

ITベンチャーで働くエンジニアのメモ帳|【Android】Intent発行時にActivityスタックをクリアする方法

しかし実際の所、こちらのコードは新規の画面を積む時には機能しない。

ここで、Flagについて整理してみよう

  • Intent.FLAG_ACTIVITY_CLEAR_TOP 同一タスクのスタック上で、すでにスタックに積まれているActivityを再度起動する際、そのActivityの上に乗っかっている他のActivityをクリアすることを指定する

  • Intent.FLAG_ACTIVITY_NEW_TASK 遷移先のAcitivityのアフィニティが異なる場合、遷移元のActivityのスタックのタスクから、新しいタスク(別のタスク)のスタック上でActivityを起動することを指定する(実はデフォルトで指定されている)

これらのFlag指定はスタック上のすでに起動したことのある画面を起動する(アフィニティが異なる場合には別タスク)という指定を意味しており、起動する際にその画面より上にある他の画面は全てクリアされる。当然、新規に画面を積んだ場合、その画面より下にある画面については何の影響も及ばない。

それでは新規に画面を積んだ時に、過去の画面をクリアするにはどうすればいいのだろうか?

 ActivityCompat.finishAffinity( this );

(this = 現在のAcitivityのインスタンス自身)

これで、同一の taskAffinity(アフィニティ) に属する現在のタスク上の画面をクリアすることができる。 (同じアプリケーションのすべての画面が、デフォルトで同じアフィニティに属することが前提条件)

注意:Android 4.0以下の場合は内部的にActivityのfinish()がコールされるだけで、意図した動作は4.1以上の場合に限る

Finish this activity, and tries to finish all activities immediately below it in the current task that have the same affinity.
On Android 4.1+ calling this method will call through to the native version of this method. For other platforms android.app.Activity.finish() will be called instead.

参考

https://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#finishAffinity(android.app.Activity)

Androidを支える技術〈I〉──60fpsを達成するモダンなGUIシステム (WEB+DB PRESS plus)

Androidを支える技術〈I〉──60fpsを達成するモダンなGUIシステム (WEB+DB PRESS plus)