iOSエンジニアのつぶやき

毎朝8:30に iOS 関連の技術について1つぶやいています。まれに釣りについてつぶやく可能性があります。

【Android】Fragment のライフサイクルを理解する

RxKotlin を使用するにあたり、それぞれのクラスでライフサイクルを理解していないと、そろそろ Android 初心者という言い訳が通用しなくなりそうなので、FragmentActivity (今回は Fragment のみ) のライフサイクルを再度しっかりと認識して良い Rx ライフを過ごせるようにしたいと思います📱

という訳でやっていく。

ライフサイクル

公式ドキュメントに掲載してあるこの図を参考にそれぞれのメソッドがどのような意味を持つのか調べてみました。

f:id:yum_fishing:20210131091358p:plain

参考: https://developer.android.com/guide/components/fragments?hl=ja#Creating

onAttach()

onAttach() メソッドは FragmentActivity に関連付けされた時に呼び出され、引数の context で関連付けした Activity が渡されます。ですので、Fragment からのイベントを Activity に通知する Listener などを実装している場合は、ここで Listener の登録処理などを行うことができます。

ちなみに以前に、上記の実装を行った記事を書いているので気になる方は見てみてください。 yamato8010.hatenablog.com

onCreate()

onCreate() メソッドは、Fragment の初期化を行うために呼び出されるメソッドです。この時点では、親の Activity のコンテンツビュー階層が初期化されていることが担保されている訳ではありません。

onCreateView()

onCreateView() メソッドは、Fragment の UI が初めて描画されるタイミングで呼び出されます。ここで、Fragment に描画したい View を返すことで任意の ViewFragment に描画することができます。また、Fragment がバックスタックから復帰する際には、このメソッドが最初に呼び出されます。

onActivityCreated()

onActivityCreated() メソッドは、親の ActivityonCreate() メソッドが完了した後に呼び出されます。この説明のみ聞くと Fragment 内のライフサイクルメソッドで ActivityonCreate() メソッドが完了したタイミングの一番初めに呼びされると思いますが、厳密には上記で記述したメソッドの順番で呼び出されていきます。つまり ActivityonCreate() メソッドのコールバックが呼び出された後に 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() は呼び出されません。また、FragmentsetRetainInstance などによって保持させている場合も同様に、画面回転時の onDestory() は呼び出されないようです。

stackoverflow.com

onDetach()

onDetach() メソッドは、FragmentActivity との関連付けが解除された時に呼び出されます。

最後に

てな感じでまとめてみましたが、意外とライフサイクルメソッドが多くて、一見すると何がいつ呼ばれるのかわからないですね。基本的には、初期化再開終了 の状態に分かれるので、その状態ごとのライフサイクルメソッドを抑えておけば問題内容な印象を受けました👀 特に破棄のタイミングは、Fragment の保持状態によっては様々なユースケースがあり、ちゃんと理解して使わないとバグの温床になりそうですね。

また、今回は RxKotlin において Fragment で保持した CompositeDisposable をどのタイミングでどのように破棄するのがいいのかを調査するために、ライフサイクルを調べましたが、前述の通り Fragment の破棄タイミングは様々なユースケースが存在するので、よしなに dispose()clear() を使い分ける必要がありそうです。onDestory() が呼ばれる時は Fragment が破棄される時なので、Fragment で保持しているサブスクリプションなどに関しては、dispose() する感じで問題なさそうですが、バックスタックなどによって追加されている場合に、購読を解除したい場合などは、dispose() してしまうと、復帰時に購読ができなくなってしまうので、onDestoryView() などで clear() を使う必要があります。

という感じで本日も以上になります👋

参考

その他の記事

yamato8010.hatenablog.com

yamato8010.hatenablog.com

yamato8010.hatenablog.com