- https://developer.android.com/jetpack/androidx/releases/lifecycle#2.4.0-alpha01
- https://medium.com/androiddevelopers/a-safer-way-to-collect-flows-from-android-uis-23080b1f8bda
UIレイヤー(Activity, Fragment等)からの、Flowのcollect方法は、大きく次の3つがあります。
// 1. kotlinx coroutineのlaunchを使う
lifecycleScope.launch {
flow.collect { ... }
}
// 2. launchWhenXXX系を使う
lifecycleScope.launchWhenStarted {
flow.collect { ... }
}
// 3. 新しく追加されたAPI
addRepeatingJob(...) {
flow.collect { ... }
}
1、2、3について、それぞれ、説明していきます。
UIで、launch関数を使うことは(ほぼ)無いと思います。バックグラウンド時など、画面が表示されていないケースでUIを更新する必要がないためです。
addRepeatingJobは、バックグラウンド時などに、ストリームを終了したいときに使います。言い換えると、重い(高価な)処理をしているときに使います。 例を上げると、callbackFlowを使って、位置情報を取得し続けるような場合です。
callbackFlow<...> {
val callback = object : LocationCallback() {
...
}
requestLocationUpdates(..., callback, ...)
...
}
上記の場合、addRepeatingJobを使うと、バックグラウンド時に位置情報の取得自体のタスクを終了することが出来るので、リソース消費を抑えることが期待出来ます。
逆に次のような場合には、あまり効果がないです。
private val _state = MutableStateFlow<...>()
val state: Flow<...> = state
特にアップストリームで、重い処理をしていないためです。
3.を使わなくても良い場合には、これを使えば良いので、大体これを使うことになると思います。
まとめると次のようになります。
- launchは使わない
- 重い処理をアップストリームで行っている場合は、addRepeatingJobを使う
- それ以外はlaunchWhenXXXを使う。だいたいこれ