ActivityとlaunchMode

Kenji Abe
6 min readJun 3, 2019
Photo by Eaters Collective on Unsplash

この前、盛大に勘違いしてることがあったので、調べ直して挙動の違いをまとめました。

launchModeはAndroidManifest.xmlにActivityごとに設定でき、Activityの起動方法を指定しします。

standard (default)

デフォルトのlaunchModeです。指定しない場合はstandardになります。

Activityが開始されるたびにスタックに積まれていきます。
バックキー等でActivityが終了するときに、最後に積まれたActivityから順番に取り除かれていきます。

もし、同じActivityを起動した場合は別のインスタンスとなり、通常通りスタックに積まれます。連続して起動した場合も同様です。

singleTop

対象のActivityが一番上にある状態で、同じActivityを起動したときに、新しくインスタンスを作らず、 onNewIntent を呼び出す処理になります。スタックに新しく積まれません。

例として、Activity BをsingleTopにします。

Activity Bが一番上にある状態で再びActivity Bを起動したときは、インスタンスが作られず、元々あるActivity BのonNewIntentが呼びされます。

一番上に対象のActivityがない場合は、通常通り別のインスタンスが作成され、スタックに積まれます。

singleTask

すでに対象のActivityがある場合は、そのインスタンスが再度利用され(onNewIntentが呼ばれる)、さらにそれまでスタックに積まれているActivityを破棄します。

Activity BをsingleTaskにします。

以下の右側の状態から、Activity Bを起動した場合はBの上にあったCとDが破棄され、Activityが一番上の状態になります。CとDはonDestroyが呼び出されます。

taskAffinity

更にsingleTaskはtaskAffinityに指定して挙動を変更することができます。

taskAffinityは雑に説明すると、別のタスクを指定するために識別子になります。通常、同じアプリケーションのAtivityは同じタスクに属することになります。taskAffinityを指定することで、別のタスクでActivityを起動することが可能になります。

Activity BにtaskAffinityを設定してみます。

このときに、Activity Bを起動すると新しくタスクが作成され、そこにActivity Bのスタックが積まれます。

このときアプリの履歴を表示すると、以下のように別のアプリのように見えます。

このときにAからCを起動する、Task1のほうにスタックは積まれ、BのほうからCを起動するとTask2のほうにスタックが積まれるという状態が可能になります。

singleInstance

最後にsingleInstanceです。singleInstanceはだいぶ特殊な感じの挙動をします。singleInstanceに指定されたActivityは別のタスクで起動され、さらにそのタスクでは、指定されたActivityのみが存在することになります。

Activity Bを起動したときは、別のタスクで起動されます。これは先程のsingleTaskとtaskAffinityを指定した挙動と同じです。

この状態で、Activity BからActivity Cを起動するとTask1のほうで起動されActivity Aの上に積まれます。Task2のほうではActivity Bしか存在しない状態になります。

この状態で、さらにActivity Bを呼び出した場合は、タスクが切り替わるのみで新しくActivity Bのインスタンスが作られず、既存のonNewIntentが呼び出されるだけになります。

分かりにくいかもしれませんが、画面の動きは次のようになります。
以下はA -> B -> Cの順で起動しています。アプリが切り替わってるような動きになっています。

更に、先程の状態からバックキーを押して戻ると、次のような画面の動きになります。

--

--

Kenji Abe

Programmer / Gamer / Google Developers Expert for Android, Kotlin / @STAR_ZERO