RxKotlin を使用するにあたり、それぞれのクラスでライフサイクルを理解していないと、そろそろ Android
初心者という言い訳が通用しなくなりそうなので、Fragment
や Activity
(今回は Fragment
のみ) のライフサイクルを再度しっかりと認識して良い Rx
ライフを過ごせるようにしたいと思います📱
という訳でやっていく。
ライフサイクル
公式ドキュメントに掲載してあるこの図を参考にそれぞれのメソッドがどのような意味を持つのか調べてみました。
参考: https://developer.android.com/guide/components/fragments?hl=ja#Creating
onAttach()
onAttach()
メソッドは Fragment
が Activity
に関連付けされた時に呼び出され、引数の context
で関連付けした Activity
が渡されます。ですので、Fragment
からのイベントを Activity
に通知する Listener
などを実装している場合は、ここで Listener
の登録処理などを行うことができます。
ちなみに以前に、上記の実装を行った記事を書いているので気になる方は見てみてください。 yamato8010.hatenablog.com
onCreate()
onCreate()
メソッドは、Fragment
の初期化を行うために呼び出されるメソッドです。この時点では、親の Activity
のコンテンツビュー階層が初期化されていることが担保されている訳ではありません。
onCreateView()
onCreateView()
メソッドは、Fragment
の UI が初めて描画されるタイミングで呼び出されます。ここで、Fragment
に描画したい View
を返すことで任意の View
を Fragment
に描画することができます。また、Fragment
がバックスタックから復帰する際には、このメソッドが最初に呼び出されます。
onActivityCreated()
onActivityCreated()
メソッドは、親の Activity
の onCreate()
メソッドが完了した後に呼び出されます。この説明のみ聞くと Fragment
内のライフサイクルメソッドで Activity
の onCreate()
メソッドが完了したタイミングの一番初めに呼びされると思いますが、厳密には上記で記述したメソッドの順番で呼び出されていきます。つまり Activity
の onCreate()
メソッドのコールバックが呼び出された後に onAttach()
、onCreate()
、onCreateView()
、onActivityCreate()
の順序で呼び出されます。
onStart()
onStart()
メソッドは、Fragment
がユーザに表示された時に呼び出されます。
onResume()
onResume()
メソッドは、Fragment
が表示されユーザ操作にインタラクティブに実行できる状態になった時に呼び出されます。
onPause()
onPause()
メソッドは、ユーザが Fragment
から離れた時に初めて呼び出されます。つまり、該当する Fragment
がフォアグランド状態にない時に呼び出されます。
onStop()
onStop()
メソッドは、Fragment
がユーザに表示されなくなった時に呼び出されます。
onDestoryView()
onDestroyView()
メソッドは、Fragment
内の View
が削除された時に呼び出されます。
onDestroy()
onDestory()
メソッドは、Fragment
自体が破棄されるタイミングで呼び出されます。バックスタックに Fragment
が追加される場合は onDestoryView()
まで呼びだされ、onDestory()
は呼び出されません。また、Fragment
が setRetainInstance
などによって保持させている場合も同様に、画面回転時の onDestory()
は呼び出されないようです。
onDetach()
onDetach()
メソッドは、Fragment
と Activity
との関連付けが解除された時に呼び出されます。
最後に
てな感じでまとめてみましたが、意外とライフサイクルメソッドが多くて、一見すると何がいつ呼ばれるのかわからないですね。基本的には、初期化
・再開
・終了
の状態に分かれるので、その状態ごとのライフサイクルメソッドを抑えておけば問題内容な印象を受けました👀 特に破棄のタイミングは、Fragment
の保持状態によっては様々なユースケースがあり、ちゃんと理解して使わないとバグの温床になりそうですね。
また、今回は RxKotlin
において Fragment
で保持した CompositeDisposable
をどのタイミングでどのように破棄するのがいいのかを調査するために、ライフサイクルを調べましたが、前述の通り Fragment
の破棄タイミングは様々なユースケースが存在するので、よしなに dispose()
、clear()
を使い分ける必要がありそうです。onDestory()
が呼ばれる時は Fragment
が破棄される時なので、Fragment
で保持しているサブスクリプションなどに関しては、dispose()
する感じで問題なさそうですが、バックスタックなどによって追加されている場合に、購読を解除したい場合などは、dispose()
してしまうと、復帰時に購読ができなくなってしまうので、onDestoryView()
などで clear()
を使う必要があります。
という感じで本日も以上になります👋
参考
- https://developer.android.com/guide/components/fragments?hl=ja
- https://qiita.com/chibi929/items/78f0d3aa2ab4a0229978
- https://stackoverflow.com/questions/23593965/when-would-fragments-ondestroyview-be-called-but-it-wouldnt-be-destroyed
- https://www.atmarkit.co.jp/ait/articles/1604/04/news011_3.html