はじめに
アプリリンク(iOSでいうところのユニバーサルリンク)を導入すると、リンクを開く時に指定したアプリで開くことができるため、ユーザーに「どのアプリで開くのか」を選択してもらう必要がなくなりUXの向上になります。
しかし、androidではデフォルトの設定だと、アプリリンクを踏んだ時の動きがおかしくなります。
アプリリンクを踏むアプリをA、アプリリンクで開きたいアプリををアプリBとした時の理想の動きとしては
- アプリBがバックグラウンドにいる
- アプリAでアプリリンクを踏むとアプリBに遷移する
- アプリBがkill状態
- アプリAでアプリリンクを踏むとアプリBが起動して遷移する
ですが、androidのデフォルトの設定だと
- アプリBがバックグラウンドにいる
- アプリAでアプリリンクを踏むとアプリAのなかでアプリBが開いているパターン
- アプリAでアプリリンクを踏むと、アプリBがもう1つ開かれて遷移するパターン
- アプリBがkill状態
- アプリAでアプリリンクを踏むとアプリAのなかでアプリBが開いているパターン
といった現象が発生します。起動しているアプリ一覧を見ると、同じアプリが複数立ち上がっているような状況で明らかに異常な状態です。
原因
androidManifest内でlaunchModeを設定していないため、デフォルトのstandard
が適用されてしまっているから
対応
AndroidManifestのactivity内にlaunchMode="singleTask"を追加する
例
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="portrait"
android:launchMode="singleTask">
launchModeについて
launchModeには4つある。
standard、singleTop、singleTask、singleInstance
standard
デフォルトの設定です。システムは常に、ターゲット タスク内でアクティビティの新しいインスタンスを作成し、そのインスタンスにインテントを渡します。
つまりジャンプ元のアプリの中で、アプリリンクで開きたいアプリを展開される。(タイトルの不具合)
singleTop
アクティビティのインスタンスがターゲット タスクの一番上に既に存在する場合は、システムはアクティビティの新しいインスタンスを作成せずに、onNewIntent() メソッドを呼び出して、インテントをそのインスタンスに渡します。
アプリリンクでアプリを開く時、
- すでにアプリが開いている時は、そのままジャンプする
- アプリが開いていない時は、ジャンプ元のアプリの中で開きたいアプリが展開される
singleTask
システムは新しいタスクのルートでアクティビティを作成し、そのアクティビティにインテントを渡します。ただし、アクティビティのインスタンスが既に存在する場合は、システムは新しいインスタンスを作成せずに、onNewIntent() メソッドを呼び出して、インテントを既存のインスタンスに渡します。
アプリリンク でアプリを開く時、
- すでにアプリが開いている時は、そのままジャンプする
- アプリが開いていない時は、新たにアプリを開いてジャンプする
singleInstance
インスタンスを保持しているタスクでシステムが他のアクティビティを起動しないことを除いて "singleTask" と同じです。アクティビティは常に、そのタスクの唯一のメンバーです。
singleTaskと同じ?要動作確認
備考
公式ではsingleTask
とsingleInstance
は推奨されていません。
しかし、同じアプリリンクでジャンプできるgoogle play storeの動きを見ると明らかにsingleTask
の動きであるため、アプリリンクを使う時はこのオプションは必須と考えても良いのではないでしょうか。