LoginSignup
21
16

More than 1 year has passed since last update.

launchWhen〇〇〇は止めてrepeatOnLifecycleを使おう!

Last updated at Posted at 2021-11-29

はじめに

皆さんは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〇〇〇でこう書いていたのを...
launchWhenStarted
    override fun onCreate(savedInstanceState: Bundle?) {
        lifecycleScope.launchWhenStarted {
            latestNewsViewModel.uiState.collect { uiState ->
                ...
            }
        }
    }

↓ こう書くだけ!

repeatOnLifecycle
    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/

参考

21
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
16