0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Android] ActivityのTaskについて

Posted at

はじめに

画像シェア機能を扱う際にTaskやRecentについて色々と調査した結果を書き残しておきます。

taskとは

Taskはアプリで使用する一連のActivityの集まりで、内部的にはBackstackを用いてActivityを管理している。

task内のbackstackの挙動操作

ActivityのlaunchModeを指定することにより、Backstackの挙動を制御できます。設定方法は主に二つある:

  1. AndroidManifest.xmlでの設定
  2. Intentのフラグを使用した設定

AndroidManifest.xmlでの設定

AndroidManifest.xml内で以下のように設定する:

<activity android:launchMode="...">
</activity>

以下はlaunchModeのオプション:

  • standard
    • Backstackの最上部に新しいActivityインスタンスを追加する
    • 異なるTask上に新しいActivityインスタンスを生成することができる
  • singleTop
    • 既にbackstackのトップにある場合はonNewIntent()を呼ぶだけ
    • backstackの一番上でなければ新しいインスタンスを生成
  • singleTask
    • 新しいBackstackのルートとしてインスタンスを作成する
    • 既存のインスタンスがある場合は、そのインスタンスにonNewIntent()を呼び出し、新しいルートにする

Flagでの設定

FLAG_ACTIVITY_NEW_TASK

  • launchModesingleTaskと同じ

FLAG_ACTIVITY_SINGLE_TOP

  • launchModesingleTopと同じ

FLAG_ACTIVITY_CLEAR_TOP

  • launchModeに該当するものはない
  • 既に存在するActivityのインスタンスがある場合、Backstack上でこのActivityの上にあるインスタンスをすべて削除し、onNewIntent()を呼び出す
  • FLAG_ACTIVITY_CLEAR_TOPFLAG_ACTIVITY_NEW_TASKは一緒に使われることが多い
    • 新しいタスクでインスタンスを生成した時にBack Stackをclearできるから

task自体の操作

Recentから消したい場合

最近開いたアプリの一覧を見ることができると思いますが、それをRecentと呼びます。
Activityでfinish()を呼び出すだけではTaskが削除されないので、Recentに残り続けてしまいます。これを回避したい場合はandroid:excludeFromRecents=”true”をmanifestに設定するか、最後のactivityをfinishAndRemoveTask() で終了させる必要があります。

taskのinstance管理

backstackの管理で使ったlaunchModeはActivityの生成を管理していて、taskを生成することに関しては何もできない。
そこでdocumentLaunchModeを使うことで、taskを生成したりすることができる。これを活用すると、一つのアプリで複数のTaskを作成し同時に二つのActivityの操作などが可能になります。
What is the difference between android:launchMode and android:documentLaunchMode attribute?

以下documentLaunchModeで使えるオプションの引用(https://developer.android.com/guide/components/activities/recents?hl=ja#attr-doclaunch)

  • intoExisting
    アクティビティがドキュメント用に既存のタスクを再利用します。これは、FLAG_ACTIVITY_MULTIPLE_TASK フラグを設定せずに FLAG_ACTIVITY_NEW_DOCUMENT フラグを設定した場合と同じです。上記のインテント フラグを使用したタスクの追加をご覧ください。

  • always
    すでにドキュメントが開いている場合でも、アクティビティがドキュメント用に新しいタスクを作成します。この値の使用は、FLAG_ACTIVITY_NEW_DOCUMENT フラグと FLAG_ACTIVITY_MULTIPLE_TASK フラグの設定と同じです。

  • noneこれがデフォルト
    アクティビティは、ドキュメント用に新しいタスクを作成しません。Recentでは、アクティビティがデフォルトとして扱われます。つまり、ユーザーが最後に実行したアクティビティから再開するアプリに対してタスクが 1 つ表示されます。

  • never
    アクティビティは、ドキュメント用に新しいタスクを作成しません。この値を設定すると、FLAG_ACTIVITY_NEW_DOCUMENT フラグと FLAG_ACTIVITY_MULTIPLE_TASK フラグの動作がオーバーライドされます。いずれかがインテントに設定されている場合、Recentでは、ユーザーが最後に実行したアクティビティから再開するアプリに対してタスクが 1 つ表示されます。

画像シェアの際の細かい知見

他アプリから画像シェアなどで自アプリを開く場合のちょっとした知見です。
singleTask vs singleInstance

  • launchMode=singleTaskでは、既存のTaskがある場合にその中のBackstackに追加されますが、singleInstanceでは既存のTaskのActivityをすべてクリアして唯一のActivityとなる。そのため、シェア画面などでは、シェア終了後に元のActivityに戻れるsingleTaskが理想的

Google files vs その他

  • Filesはおそらく独自定義のせいでシェアした際のactivityがGoogle FilesのTask上に重なってしまう
  • 以下を参考に、新しいintentをonCreateで呼ぶと通常通りFilesではなくこちらのアプリの上にactivityが作られる
@Override
protected void onCreate(Bundle state) {
    super.onCreate(state);
    setContentView(R.layout.main);

    if (!isTaskRoot()) { // Or check getIntent().getFlags() for SINGLE_INSTANCE
        Intent newIntent = new Intent(getIntent());
        newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(newIntent);
        finish();
    }
}

さいごに

間違いなどありましたらコメントお願いします。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?