ちょっと話題の記事

Android Tips #21 画面遷移パターンでみる Activity のライフサイクル

2012.10.19

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

Activity のライフサイクルは Android アプリを開発する上で基本中の基本です。 基本的なライフサイクルは知っていないとそもそも実装はできませんが、もっと細かい制御を行いたいとき(例えば、ホームキーを押したときだけ挙動を変えるとか)はもう一歩ライフサイクルについての理解が必要になってきます。 ということで今回は Activity のライフサイクルについて、いろいろな画面遷移パターンでどのようなメソッドが呼ばれるのか確認してみました。

Activity のライフサイクルについて

基本的なライフサイクルメソッド

まず Activity のライフサイクルについておさらいしておきましょう。 以下のような感じです。

メソッド名 呼ばれるタイミング
onCreate() Activityが初めて作られたとき
onStart() Activityが開始されたとき
onResume() Activityが表示されたとき
onRestart() Activityが再度開始されたとき
onPause() 別のActivityが表示されるとき
onStop() Activityが表示されなくなったとき
onDestroy() Activityがメモリから開放される直前

この辺はかなり初歩なので、Androidアプリ開発者は知っていて当然ですね。

その他のライフサイクルメソッド

他にもいくつかのライフサイクルメソッドがあります。上記に挙げたメソッドよりは利用頻度は低いですが、知っておくと便利なメソッドです。

メソッド名 呼ばれるタイミング
onApplyThemeResource() Activityにテーマが適用されたとき
onPostCreate() Activityの開始が完了したとき
onPostResume() Activityのレジュームが完了したとき
onActivityResult() 他のActivityにリクエストした結果が返ってきたとき
onNewIntent() 新しくIntentが発行されて呼ばれたとき(singleTopのときのみ)
onSaveInstanceState() Activityの状態を保存すべきとき
onRestoreInstanceState() Intentで呼ばれ、Activityの状態を復元するとき
onUserLeaveHint() Activityがユーザー操作から離れたとき

基本的なライフサイクルメソッドを補うかのように、さまざまなタイミングでハンドリングできるのが分かると思います。これらのメソッドをうまく使うと、いろいろと細かい制御ができるようになります。

画面遷移パターンで呼ばれるメソッドを確認する

上記すべてのメソッドが呼ばれたときのログをとり、いくつかの画面遷移のパターンを操作したときに呼ばれるメソッドとその順番を確認してみました。

Activity を起動する

アプリ起動後、初めて表示されたときの場合です。

onApplyThemeResource() は onCreate() より前に呼ばれています。

Activity の表示中にバックキーを押す

Activity の表示中にバックキーを押して Activity を閉じました。

Activity にはもう戻ってこないので、 onDestroy() まで呼ばれ完全に破棄されます。

Activity の表示中にホームキーを押す

Activity の表示中にホームキーを押して、ホーム画面に戻りました。

onUserLeaveHint() が呼ばれています。これを使うとホームキーを押したときの処理を実装できます。しかし onUserLeaveHint() は他にも呼ばれるタイミングがあるので注意が必要です。また onSaveInstanceState() で Activity の状態を保管しています。

停止中の Activity をホーム画面から再度開く

アプリを起動した状態でホーム画面に戻ると Activity は停止状態になります。その状態でアプリをもう一度開きました。

Activity はもう生成しているので、 onCreate() などは呼ばれません。onStart() の前に onRestart() が呼ばれています。

他の Activity に遷移する

ActivityA から ActivityB に遷移するボタンを置いて、ActivityA の表示後に ActivityBに遷移させました。

非表示になる ActivityA で onUserLeaveHint() が呼ばれています。なので、ホームボタンの制御を考えるときには、 onUserLeaveHint() が他の画面への遷移時にも実行されるということを注意しなければいけません。また ActivityB の表示までのライフサイクル完了後に ActivityA の onSaveInstanceState() と onStop() が呼ばれています。ActivityA が非表示になってからの処理は onStop() に書くようにしましょう(例えば ImageView に表示されている Bitmap の破棄など)。

他の Activity から戻ってくる

ActivityA → ActivityB という遷移をしている状態でバックキーを押し、 ActivityA に戻りました。

まず ActivityB の onPause() が呼ばれ、そのあとに ActivityA が再開します。ActivityA の表示が終わったあとに不要となった ActivityB を停止、破棄するメソッドが呼ばれています。

Activity の表示中にスリープ状態にする

Activity の表示中に画面OFF(スリープ状態)にしました。

他の画面に遷移したときと同じメソッドが呼ばれます。

スリープ状態から Activity を再度表示する

Activity の表示した状態でスリープさせ、そのあとにもう一度表示させました。

通常の再開時のライフサイクルです。ちなみにこれらのメソッドは画面がONになったとき(ロック画面が表示されたとき)に呼ばれます。

長時間放置したあとに Activity を表示する

Activity が停止した状態で長時間放置したり、他のアプリがメモリ要求したりすると停止中のアプリは一度破棄され、次に呼ばれたときに Activity を生成し直します。 この状態は Android 4.0 から「設定 > 開発者向けオプション > アクティビティを保持しない」にチェックをつけると再現できるので、今回はそれを使って試しました。

Activity を生成するときの通常のライフサイクルメソッドが呼ばれているように見えますが onRestoreInstanceState() が混じっています。これは Activity 停止時に onSaveInstanceState() で保存した状態を復元するために呼ばれています。

まとめ

Android の画面遷移のパターンは実にさまざまです。アプリ起動中に他のアプリが起動できたり、Intent を使ってアプリ間連携が自在だったりします。Intent の種類によってアプリ内の画面遷移はさまざま 考えられます。そのため画面遷移するときにどのようなライフサイクルメソッドが、どのような順番で呼ばれるか理解することはとても重要です。 まずはワイヤーフレームどおりに画面遷移する実装だけしておいて、ライフサイクルメソッドのログをとり、どのタイミングでどういう処理を実装すれば良いか検討する工程を入れておくと良いと思います。

参考