はじめに
皆さんはlaunchWhenCreated, launchWhenStarted, launchWhenResumedを使ってますか?coroutinesでライフサイクルを意識して書く場合、必須とでも言うべきメソッドです。
ですが、Flowでこれらを利用するのは避けたほうが良いです。なぜか?
launchWhen〇〇〇ではFlowが完全には停止せず、リソースが消費される可能性があるからです。
Lifecycle が STOPPED の場合、前者の API はコルーチンをキャンセルするのではなく停止するため、アップストリーム フローはバックグラウンドでアクティブのままにされ、新しいアイテムが出力される可能性やリソースが浪費される可能性があります。
launchWhen〇〇〇は将来的に廃止予定
また、launchWhen〇〇〇は将来的に下記リンクにある通りでThis API will be removed in a future release.
とのこと。
今後はrepeatOnLifecycleを使おう
では何を使うべきか。androidx.lifecycle:lifecycle-runtime-ktx:2.4.0-alpha01
からrepeatOnLifecycle APIが利用できるようになっており、これを使うように推奨されています。2.4.0は2021/10/27にStableになりました。
書き方は非常に簡単。
- launchWhen〇〇〇でこう書いていたのを...
override fun onCreate(savedInstanceState: Bundle?) {
lifecycleScope.launchWhenStarted {
latestNewsViewModel.uiState.collect { uiState ->
...
}
}
}
↓ こう書くだけ!
override fun onCreate(savedInstanceState: Bundle?) {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
latestNewsViewModel.uiState.collect { uiState ->
...
}
}
}
}
上記の例だと、repeatOnLifecycleはLifecycle が STOPPEDの際にJobをキャンセルしてくれて、STARTEDになったら再度Jobをlaunchしてくれるのでリソースの消費を防げます。
実は、他に細かい動作の違いとかあるので書こうと思ったんですが、moriさんのブログがとてもきれいにまとまっていたためこちらにリンク置いときます。非常に勉強になります。
https://at-sushi.work/blog/35/
参考