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プロパティを呼んでいる。 ↩


