2011年10月26日水曜日

onActivityResultイベントが発生するタイミング

Androidアプリケーション開発のうえで調べたこと。

Windowsアプリケーションでは、フォームやダイアログをモーダルもしくはモーダレスで表示できますが、Androidのアクティビティにも同じような考え方があります。

まず、フォームやダイアログの表示方法と戻り値の有無について整理しておきましょう。

  • Showメソッドによってモーダレスで表示したフォームもしくはダイアログは、呼び出し元に戻り値を返すことはありません。
  • ShowDialogメソッドによってモーダル表示したフォームもしくはダイアログは、呼び出し元に戻り値(DialogResult)を返します。

Androidでも、アクティビティからアクティビへ遷移するときに、同じような区別があります。
ここで遷移元のアクティビティをA、遷移先のアクティビティをBとします。

  • AでStartActivityメソッドを使ってBへ遷移したとき、AはBから戻り値を取得できません。
  • AでStartActivityForResultメソッドを使ってBへ遷移したとき、AはBから戻り値を取得できます。また、Bが非表示になると基本的にはAがアクティブになります。

ここまでは、WindowsアプリケーションとAndroidアプリケーションでとてもよく似ていますが、異なることがあります。それは、AndroidアプリケーションでStartActivityForResultメソッドを使ってアクティビティを表示したときの挙動です。

呼び出し先であるBから、呼び出し元であるAへ制御が戻るときに発生するイベントが存在するということです。

発生するイベントは、onActivityResultです。

では、ここで問題。

onActivityResultは、下記ライフサイクルのどこで発生するでしょうか?



正解は、「onResumeの前」です。

このonActivityResult→onResumeという発生順は次のとおり保障されています。

http://developer.android.com/intl/ja/reference/android/app/Activity.html#onActivityResult(int, int, android.content.Intent)

上記解説に"You will receive this call immediately before onResume() when your activity is re-starting."とあります。

onActivityResultがonResumeより前に呼び出されることを利用すれば、たとえばAというアクティビティがBというアクティビティをstartActivityForResultで呼び出したときに、Bからの戻り値でAの画面表示を変更するということも可能になります。

もう少し具体的に書くと、Aの画面表示処理で、Bから戻ってきたときにだけ実行したい処理があるときに、onResumeではなくonActivityResultに書くとスマートです。

onResumeは、あらゆるアクティビティからの遷移で発生する可能性がありますが、onActivityResultであれば、startActivityForResultで遷移したアクティビティからの戻りによる発生に限定できますので。

まとめ:アクティビティからの戻り値を利用した画面表示をしたいときは、StartActivityForResultとonActivityResultのコンビを使うと便利。onActivityResultがonResumeの前に発生することは保障されている。