Android Kotlin基礎講座 04.1: ライフサイクルとログ情報について
目次
タスク:ライフサイクルメソッドについて知り、基本ログを追加する
全てのアクティビティおよびフラグメントにはライフサイクルがあります。以下では蝶々に例えてライフサイクルについて説明しています。蝶々が生まれた時から成長して死に至るまでの過程で状態が変わっているのが分かります。
これと一緒でアクティビティのライフサイクルもアクティビティが成り得る異なる状態から構成されています。アクティビティが最初に作られた時から最終的に破棄され、メモリがシステムによって再利用されるまでの間の状態です。ユーザーがアプリを起動し、アクティビティ間を遷移したり、アプリの内外を遷移したり、アプリを終了させたりする際にアクティビティは状態を変化させます。以下のダイアグラムは全てのアクティビティのライフサイクル状態を表しています。名前に示されているように、アクティビティの状態を表しています。
アクティビティのライフサイクル状態が変わったときに、挙動を変更したり、あるコードを実行させたいといったことはよくあります。したがって、Activityクラス自身やAppCompatActivityなどのサブクラスは全てライフサイクルコールバックメソッドのセットを実装しています。Androidはこれらのコールバックをアクティビティがある状態から別の状態に移るときに呼び出します。またそれらのメソッドを自身のアクティビティ内でオーバーライドし、ライフサイクル状態の変化に合わせて処理を行わせるようにすることもできます。下のダイアグラムはオーバーライド可能なコールバックとライフサイクル状態を表しています。
フラグメントにもライフサイクルがあります。フラグメントのライフサイクルはアクティビティのライフサイクルに似ているため、学ぶことの多くは両方に当てはまります。この記事ではアクティビティのライフサイクルに焦点を当てています。なぜならこれこそがAndroidの土台となる部分であり、またシンプルなアプリにおいて観察するのが容易であるためです。
以下はフラグメントのライフサイクルに対応するダイアグラムです。
これらのコールバックがいつ呼び出され、何がなされているのかについて知ることは重要です。しかしこれらのダイアグラムは複雑で困惑するでしょう。この記事では、それぞれの状態とコールバックが意味することをただ読む代わりに、実際に手を動かして作業をしながら何が行われているのかを探索し、理解を深めていきます。
ステップ1:onCreate()メソッドについて調べ、ログを追加する
Androidライフサイクルで何が起こっているのかを知るためには、いつ異なるライフサイクルメソッドが呼び出されるのかを知ることが重要です。これはDessertClickerアプリ内のどこが間違っているのかを突き詰める手助けになります。
そうするためのシンプルな方法はAndroid logging APIを使うことです。ログを使うことでアプリ動作中にコンソールにショートメッセージを表示し、異なるコールバックが呼び出された時に知らせるようにすることができます。
- DessertClicker starter appをダウンロードし、Android Studioで開いてください。
- コンパイルし、アプリを起動してください。デザートの画像を何回かタップしてください。Desserts Soldと合計額の値がどのように変化するか確認してください。
- MainActivityktを開き、onCreate()メソッドを見てください。
override fun onCreate(savedInstanceState: Bundle?) {
...
}
このアクティビティのライフサイクルダイアグラムの中で、onCreate()メソッドは以前にも使用しているため、このコールバックを認識していたかもしれません。これは全てのアクティビティが実装しているメソッドの一つです。onCreate()メソッドはアクティビティの初期化の際に一度だけ行わせたい処理を記述するためのメソッドです。例えば、onCreate()の中でレイアウトをインフレートしたり、クリックリスナーを定義したり、データバインディングのセットアップを行ったりします。
onCreate()メソッドは一度だけ、アクティビティが初期化された後(Activityオブジェクトがメモリ上で作られるとき)に呼び出されます。onCreate()が実行された後、アクティビティは上記ダイアグラムのCreatedになったと考えられます。
Note: onCreate()メソッドはオーバーライドなので、その中でsuper.onCreate()を即座に呼び出さなければなりません。同じことが他のライフサイクルメソッドにも言えます。
- onCreate()メソッドの中のsuper.onCreate()の直後に以下のコードを追加してください。必要であればLogクラスをインポートしてください。(Alt+Enter、Macの場合Option+Enterを押してImportを選択することでインポートできます)
Log.i("MainActivity", "onCreate Called")
LogクラスはLogcatにメッセージを表示します。このコマンドには以下の三要素があります。
The Log
class writes messages to the Logcat. There are three parts to this command:
- ログメッセージの重要度:今回の場合はLog.i()メソッドは何か情報を知らせるメッセージを表示する際に用います。Logクラスの他のメソッドにはエラー用のLog.e()や、警告用のLog.w()があります。
- タグ:今回の場合は”MainActivity”です。タグはLogcatでログメッセージを見つけやすくするためのstringです。タグには一般的にはクラスの名前が使われます。
- 実際のログメッセージ:短い文で、今回の場合は”onCreate called”がそれにあたります。
- コンパイルしてアプリを起動してください。アプリ内の挙動に変化はありませんがAndroid Studioの画面下部にあるLogcatタブをクリックしてください。
Logcatはログメッセージ用のコンソールです。Log.i()メソッドや他のLogクラスのメソッドによって明示的に送ったメッセージを含む、アプリに関するAndroidからのメッセージがここに表示されます。 - Logcatの検索フィールドにI/MainActivityと入力してください。
Logcatには多くのメッセージが含まれます。そのほとんどは必要のないメッセージです。色々な方法でそれらをフィルタリングすることができますが、検索が最も簡単です。MainActivityをログのタグに設定しているので、タグを使ってフィルタリングできます。I/をタグの前に追加することでLog.i()によって作られたある情報用のメッセージのみを表示させることができます。
ログメッセージには日付と時間、パッケージ名(com.example.android.dessertclicker)、ログタグ(I/から始まる部分)、そして実際のメッセージが含まれます。ログにこのメッセージが表示されることで、onCreate()が実行されたことを確認することができました。
ステップ2:onStart()メソッドを実装する
onStart()ライフサイクルメソッドはonCreate()の直後に呼び出されます。onStart()が実行された後、アクティビティは画面上で見ることができるようになります。初期化するために一度だけ呼び出されるonCreate()と違って、onStart()はライフサイクルの中で何度でも呼び出されることがあります。
onStart()は対応するonStop()ライフサイクルメソッドとペアになっていることを確認してください。ユーザーがアプリを起動し、端末のホーム画面に戻った場合、アクティビティは停止され、画面上に表示されなくなります。
- Android StudioでMainActivity.ktを開き、Code > Override Methodsを選択するか、Control+oを押してください。クラス中のオーバーライドできる全メソッドの一覧が表示されたダイアログが現れます。
- onStartと入力して正しいメソッドを検索してください。次にマッチしたアイテムにスクロールするためにはカーソルキーの下を使います。リストからonStart()を選び、OKをクリックしてオーバーライドコードの定型文を挿入します。コードは以下のようになります。
override fun onStart() {
super.onStart()
}
Tip: Android Studioはクラス中の次に適切な位置にオーバーライドされたメソッドを挿入してくれます。ライフサイクルオーバライドを特定の場所(クラスの終わりなど)に置きたい場合は、Override Methodsを使う前に、insertion pointを設定してください。
- onStart()メソッドの中にログメッセージを追加してください。
override fun onStart() {
super.onStart()
Log.i("MainActivity", "onStart Called")
}
- コンパイルしてアプリを起動してください。Logcatを開いて、検索フィールドにI/MainActivityと入力してください。onCreate()とonStart()メソッドの両方が順番に呼び出され、アクティビティが画面上で見えるようになっていることを確認してください。
- 端末のホームボタンを押して、最近の画面を使ってアクティビティに戻ってください。アクティビティのDessert Soldや合計金額の値が全て同じまま再開されていることを確認してください。またonStart()がLogcatに再度表示されています。一方で、onCreate()は再び呼び出されていないことを確認してください。
Note: 端末で試してライフサイクルコールバックを観察したように、端末の向きを変えると異常な挙動が起こることを確認してみてください。この挙動については次の記事で学習します。