1. HOME
  2. ブログ
  3. IT技術
  4. 【Android】【Kotlin】Fragmentのライフサイクルに合わせて自動に参照を消してくれる仕組みを作る

【Android】【Kotlin】Fragmentのライフサイクルに合わせて自動に参照を消してくれる仕組みを作る

はじめに

Fragment で View の参照を持っている場合、 onDestoryView() で参照を取り除いておくべきらしい。

恥ずかしながら、このことを最近知りました。

ViewBindingのガイドの例では

更に続けて

注: フラグメントはビューよりも持続します。フラグメントの onDestroyView() メソッドでバインディング クラスのインスタンスへの参照をすべてクリーンアップしてください。

と書かれています。

なるほど?

と思うと同時に、面倒くさいし実運用では onDestoryView() での = null を忘れそうな気がしました。

とりあえず、 DelegatedProperties を使えば解決できそうです。

車輪の再発明になるかもですが、自分で使いやすいように作っていこうと思います。

Fragmentのライフサイクルに合わせて自動に参照を消してくれる仕組みを作る

ライフサイクルに合わせて参照を消してくれる仕組みは、以前から個人的にKotterKnifeから一部拝借して使っていました。

https://gist.github.com/chrisbanes/fc4392dcbdc0aa5d99147dc551616676#file-kotterknife-kt-L123

ただ↑は ReadOnlyProperty なので、var の変数では使えないです。これをベースにしてReadWritePropertyで作り直すことにしました。

ライフサイクルと紐付けるための LifecycleObserver  が Deprecated になっているので代わりの DefaultLifecycleObserver を使います。

これで、 onDestory() がライフサイクルに合わせて呼び出されて、参照を消せるようになりました。

加えて↓

↑拡張関数を作成して Fragment で使いやすくすることで

公式 ViewBinding ガイドの例を以下のように書き換えることができます。

だいぶスッキリしましたね。

実装中に心配になったonDestroyの呼び出しタイミング

DefaultLifecycleObserveroverride fun onDestroy() の呼び出しタイミングってどこなんだろう?

ということで DefaultLifecycleObserver.onDestory() の呼び出しを遡ってみることにしました。

FullLifecycleObserverAdapter.onStateChangedLifecycle.Event.ON_DESTROY のときに呼び出されているんですねー

そのまま更に辿ると、 Fragment.performDestroyView() にて Lifecycle.Event.ON_DESTROY を設定していることがわかりました。

よく読んでみると、直後に Fragment.onDestroyView() を呼び出していますね。

つまり、

DefaultLifecycleObserveroverride fun onDestroy() は、Fragment の onDestoryView() 直前で呼び出されている。

ということらしい。なるほど勉強になった。

おまけ

mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);

mViewLifecycleOwner は、 Fragment.getViewLifecycleOwner() で取得できる LifecycleOwner だ。

なるほど、やっぱり Fragment.getLifecycle() で取得できるライフサイクルとは別物で、イベントのタイミングが微妙に違うんですねー

改めて、Fragement でライフサイクルと View を絡めるときは Fragment.getViewLifecycleOwner() を使うべき、ということがなんとなくわかった。

関連記事

採用情報

\ あの有名サービスに参画!? /

バックエンドエンジニア

\ クリエイティブの最前線 /

フロントエンドエンジニア

\ 世界を変える…! /

Androidエンジニア

\ みんなが使うアプリを創る /

iOSエンジニア