Androidのアクティビティとタスク

Last edited on 2012/07/08 (日) - 17:13

Androidのアクティビティとタスクの振る舞いについて、developer サイトの 「開発の基礎」のページ のアクティビティとタスクの章を読んでみました。

AndroidではIntentを使ってアクティビティから別のアクティビティを呼びだすことができます。これらの関連するアクティビティをスタックにまとめたものがタスクです。アクティビティが他のアクティビティをIntentで呼び出し、自分と同じタスクのスタックに積んでいき、Back(戻る)ボタンで積んだアクティビティをポップするというのがAndroid標準の動作です。しかし、このタスクの振る舞いはアクティビティを呼び出すときのIntentに与えるフラグや、呼び出すアクティビティそのものの属性で変わってきます。

「開発の基礎」のページでこれを丁寧に解説してあります。じっくり読んでみてすごくよくわかりました。実際にはどういうところで使われているのだろうと思って実例を探してみました。(ただし推測も混じっているので必ずそう動いている確信はありません)

[1] ギャラリーからの共有

ギャラリーアプリのAndroidManifest.xml を見ると、clearTaskOnLauch 属性が True になっていました。ということは、ギャラリーから他のアクティビティを呼び出した場合、一旦ホームに戻ってしまうと呼び出したアクティビティはクリアされてしまうので、再びギャラリーを起動してもギャラリーが立ち上がるだけです。

[2] 他のアプリから Gmailの呼び出し

Gmail の AndroidManifest.xml を見ると、allowTaskReparentng 属性が True になっていました。ということは、他のアプリから呼び出されてスタックに積まれたGamilアクティビティは、Gmailと親和性(Affinity)のあるタスクがフォアグラウンドに移るとそちらのタスクに移動することになります。たとえば、

・Gmailを起動し、新規作成する
・新規作成の画面のまま、一旦ホームに戻る
・ギャラリーを立ち上げ、適当な写真の共有メニューからGmailを起動する
・一旦ホームに戻る。

GmailのLaunchモードは singleTaskでもsingleInstanceでもないので、この時点でのタスクは(1)Gmailのリスト→新規作成 と (2)ギャラリー → Gmail作成 の2つのタスクがあると思われます。

・Gmailを起動することで (1)のタスクに切り換える

すると、(2)のギャラリーから読んだGmail作成画面が現れます。さらに、Backボタンで戻ると (1)の新規作成画面になります。つまり、(2)のGmailアクティビティが(1)のタスクに移動したように見えます。

[3] ブラウザからのページ共有

ブラウザのAndroidManifest.xml を見ると、まずlauch mode が singleTask になっています。つまり、ブラウザは必ずタスクのルートになります。他のアプリからブラウザを呼び出しても、自分のタスクに積むことはできず、新たなタスクになってしまいます。また、alwaysRetainTaskState 属性が True になっており、これでタスクのスタックがいつまでも保存されます。

しかし、ブラウザから「ページの共有」で他のアプリを呼んだときに、そのまま一旦ホームに戻り、次にブラウザを起動してもブラウザが立ち上がるだけです。どうしてでしょ?

実はブラウザから「ページの共有」で他のアプリを呼ぶときに、Intent に FLAG_ACTIVITY_PREVIOUS_IS_TOP というフラグを付けています。このフラグは、Intentで呼んだアクティビティはすぐに終了するアクティビティなので、自分がタスクのトップであると見なしていいよ、というフラグらしいのです。なので、次にブラウザのタスクに切り換えた時にブラウザ自身がタスクのトップと見なされるのではないかと思います。(ちょっとこのあたり確信ない)

************************************************************************************************************

というようなことになっているのですが、一般のユーザにこんなことを説明しても、これだからAndroidって... と言われて嫌われるだけのような気がします。うんちくを語るのは相手を選びましょう。

一般ユーザにとっては、なんだかわからないけど無意識のうちにうまく使えているというのが一番だと思います。アクティビティとタスクの設計によっていろいろできてしまうので、奇妙な動きをしない、予想通りの使い方ができる、というふうにしなければいけないのだと思います。