Fragment
クラスは LifecycleOwner
インターフェイスを実装しています。
しかし LifecycleOwner
オブジェクトとして、Fragment
オブジェクト自身ではなく、
Fragment.viewLifecycleOwner
プロパティが返すオブジェクトを使うべき場合があります。
本稿では、まず前提となる ライフサイクル、Lifecycle
クラス、LifecycleOwner
インターフェイス について簡単に説明してから、その本題について説明します。
ライフサイクル
アクティビティやフラグメントにはライフサイクルがあります。
画像は以下より。
- アクティビティのライフサイクルについて | Android デベロッパー | Android Developers
- フラグメント | Android デベロッパー | Android Developers
Lifecycle
クラス
Lifecycle
クラスはアクティビティやフラグメントのライフサイクルを表します。
Lifecycle.addObserver(LifecycleObserver)
関数を用いることで、以下のライフサイクルイベントを監視することができます。
ライフサイクルイベント | 発行タイミング |
---|---|
ON_CREATE |
onCreate の後 |
ON_START |
onStart の後 |
ON_RESUME |
onResume の後 |
ON_PAUSE |
onPause の前 |
ON_STOP |
onStop の前 |
ON_DESTORY |
onDestory の前 |
LifecycleOwner
インターフェイス
Lifecycle
オブジェクトは LifecycleOwner
インターフェイスの lifecycle
プロパティから取得できます。
Activity
クラスや Fragment
クラスは LifecycleOwner
インターフェイスを実装しています。
ライフサイクルイベントを監視する主要な API
次のような API は Lifecycle
オブジェクトが発行するライフサイクルイベントを監視して動作の変更を行います。
API | 説明 |
---|---|
Lifecycle.coroutineScope プロパティLifecycleOwner.lifecycleScope プロパティ1
|
ON_DESTORY イベントでキャンセルされる CoroutineScope オブジェクトを返す。 |
LiveData.observe(LifecycleOwner, Observer<Object>) 関数 |
LiveData オブジェクトの監視を開始する。ON_DESTORY イベントで解除される。 |
他にも色々あるはずですが、
不要になったら自動で解除するようなものは基本的に
ON_DESTROY
イベントで解除すると考えられます。
フラグメントのライフサイクルの問題
フラグメントのライフサイクルを再度確認してみましょう。
フラグメントでは onDestory
に行かず onCreateView
に戻る流れがあります。
つまり、onCreateView
や onActivityCreated
などのライフサイクル関数で開始した処理
を ON_DESTROY
イベントで解除しようとしていると、
解除していないのに再度開始してしまうことが起こります。
例えば onCreateView
で LiveData.observe
関数を呼び出した場合だと、値が変更された時の処理が多重に呼ばれることになります。
Fragment.viewLifecycleOwner
プロパティで解決
この問題を解決するのが Fragment.viewLifecycleOwner
プロパティです。
このプロパティは LifecycleOwner
オブジェクトを返しますが、
それは Fragment
クラスが実装しているものとは異なります。
この LifecycleOwner
オブジェクトの lifecycle
プロパティが返す Lifecycle
オブジェクトは、ON_CREATE
イベントと ON_DESTROY
イベントの発行タイミングが次のようになります。(他の4イベントは同じです。)
ライフサイクルイベント | 発行タイミング |
---|---|
ON_CREATE |
onViewStateRestored の後(onCreateView より後) |
ON_DESTROY |
onDestroyView の前 |
そのため onCreateView
から onViewStateRestored
までの間に開始した処理を
onDestroyView
で解除することができ、
すなわち onDestory
が呼ばれずに再度 onCreateView
が呼ばれても、多重に実行されるということがないようにできます。
画像は下記より。Android 公式の図より細かくなっています。
まとめ
Fragment
オブジェクト自身を LifecycleOwner
として使うと問題がある場合があります。
代わりに Fragment.viewLifecycleOwner
プロパティが返す LifecycleOwner
オブジェクトを使用することを検討しましょう。
Fragment.viewLifecycleOwner
プロパティを使うべきなのは、
onCreateView
もしくはそれ以降のライフサイクル関数で開始した処理を ON_DESTROY
イベントで解除する場合です。
また、LifecycleOwner
の拡張関数・拡張プロパティを、そうと意識せず、viewLifecycleOwner
プロパティから使うべき場合に Fragment
オブジェクトから直接使ってしまわないようにも注意しましょう。
参考資料
/以上
-
LifecycleOwner.lifecycleScope
プロパティは内部でLifecycle.coroutineScope
プロパティを呼んでいる。 ↩