以下はAndroid開発者であれば何度も見たことがあるはずの、Activityライフサイクルの状態遷移図です。
これを、今回の解説用に加筆したのが以下の状態遷移図です。
ライフサイクルイベントとしてonRestoreInstanceState()、onPostCreat()、onResumeFragments()、onSaveInstanceState()を追加しています。また、「Activityが状態を伴って再起動する遷移」を追加してあります。これら加筆したライフサイクルイベントと遷移については後述します。
さて、普通のAndroidアプリには、必ず1つ以上のActivityが必要です。
例えば、アプリ起動時などのActivity起動時には、画面が表示されるまでに【1】onCreate()、【2】onStart()、【3】onPostCreate()、【4】onResume()、【5】onResumeFragments()という順番でライフサイクルイベントが呼び出されます。
onRestoreInstanceState()は状態復元を行う必要がある場合にのみ呼び出されます。
アプリ終了時などのActivityの終了時には【1】onPause()、【2】onSaveInstanceState()、【3】onStop()、【4】onDestroy()という順番でライフサイクルイベントが呼び出されます。
アプリがバックグラウンドから復帰した場合は、onRestart()が呼び出されます。
必要な初期化処理や終了処理、状態保存や状態復元は、どのライフサイクルイベントで行うのがいいのでしょうか。その指針を以下で解説します。
なお、解説中の「状態の復元」に関する記載は、必ずそうしなければならないわけではなく、そうすることで「分かりやすく問題が発生しにくいコードになるであろう」という筆者の経験則が書かれていることを留意ください。
他の方法でも適切な設計の下に実装されていれば、十分問題が発生しにくいコードになり得ます。状態の復元が複数のタイミングで行えるのは、「設計の柔軟性」のためなのです。
onCreate()は、Activityが生存している間ずっと、必要な処理の初期化を行います。例えば、setContetView()によるレイアウト設定、リスナーの設定、ServiceやBroadcastReceiverの設定などです。savedInstanceStateが引数で渡されてきますが、「状態の復元は、ここでは行わない」ことを推奨します。
対応するonDestroy()では、ServiceやBroadcastReceiverを停止します。画面の向きが変わった場合でもonDestroy()が呼び出された後、状態を伴ってonCreate()から再開されるので、縦画面と横画面でレイアウトが違う場合は、onCreate()で向きを判定してからレイアウトXMLを設定する必要があります。
onStart()はActivityが表示される前に呼び出されるライフサイクルイベントです。
対応するonStop()はActivityが非表示になったら呼び出されるライフサイクルイベントです。
onRestoreInstanceState()はActivityの状態を復元する必要がある場合に呼び出されるライフサイクルイベントです。必要がない場合には呼び出されないことに注意してください。
ここでActivityの状態を復元することを推奨します。つまり、onCreate()、onStart()では、Activityの状態を参照しないように各種処理を実行しますが、それで困ることはないはずです。
注意すべき点は、状態が変更された際に呼び出されるリスナー(例えばTextWatcherなど)が、状態の復元で動作し、予期せぬ振る舞いをしてしまわないかどうかです。これは次に説明するonPostCreate()で解決するといいでしょう。
対応するonSaveInstanceState()では、Activityの状態を保存します。Activityの状態が保存できるタイミングはここだけです。
onPostCreate()は、onStart()またはonRestoreInstanceState()の後に呼び出されるライフサイクルイベントです。onRestoreInstanceState()は状態の復元が必要な場合にのみ呼び出されるのに対し、onPostCreate()は常に呼び出されます。状態の復元よりも後に行いたい初期化処理などは、ここで行います。
ただし、アプリのバックグラウンドプロセスからの復帰の場合、onCreate()と異なり何度も呼び出されてしまうため、既に初期化済みであるかどうかを判定する必要があります。
また、その判定条件はonSaveInstanceState()で保存してはなりません。例えば「リスナーが設定されていなければ設定する」「onRestart()でバックグラウンドプロセスから復帰したことを表すフラグをtrueにして、そのフラグで判定する」などになるでしょう。
onResume()はActivityがユーザー操作を行えるようになる直前に呼び出されるライフサイクルイベントです。このメソッドは、アプリ内の他のActivityから復帰してきた際にも呼び出されるメソッドでもあります。
対応するonPause()は、アプリ内の他のActivityに遷移する際にも呼び出されるメソッドです。そのActivityのための負荷の高い処理(通信やアニメーションなど)を停止したり再開したりするのは、これらライフサイクルイベントで行います。
また、onPause()では、アプリの永続化データを保存する必要もあります。onPause()呼び出し後、onStop()、onDestroy()と進まずにメモリ不足によりアプリプロセスが終了することもあれば、ユーザー操作でアプリプロセスが終了されることもあるためです。
onResumeFragments()は、そのActivityの持つ全てのFragmentが開始された後に呼び出されるライフサイクルイベントです。複数のFragmentを横断して処理する必要がある場合は、このコールバックイベントで行います。
onRestart()は、HOMEキーなどでアプリがバックグラウンドタスクになり、再びフォアグラウンドタスクになった際に呼び出されるライフサイクルイベントです。アプリがバックグラウンドから復帰した際に行いたい処理はここで実行します。
Copyright © ITmedia, Inc. All Rights Reserved.