StateFlowについて
StateFlow についてまとめておきます。Androidoアプリを作っていて、戸惑うのがStateFlowです。
慣れていないと使い方がいまいちしっくりきません。
そもそも Flow とは
Flow は Kotlin の 非同期データストリーム を扱うための仕組みです。
「値が順番に流れてくるパイプ」のようなもの。
例えば、ボタンが押されたイベント、データベースの更新通知、ネットワークからの受信データなどがそうです。
ただし、普通の Flow は 一度 collect しないと値が流れ始めない(コールドストリーム) という特徴があります。
そしてStateFlowとは
StateFlow は Flow を拡張した特殊な Flow で、以下の特徴があります。
常に最新の値を保持する
→ 「状態(State)」を表すのに適している。
初期値が必須
→ 生成時に必ず値を与える。
ホットストリーム
→ 誰も collect していなくても最新の値を持ち続ける。
複数の collector が同時に購読できる
→ 例えば UI の複数画面が同じ状態を観察可能。
必要ライブラリ
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
ViewModelの例
class CounterViewModel {
// 内部的に更新するための MutableStateFlow
private val _count = MutableStateFlow(0)
// 外部に公開するのは StateFlow(読み取り専用)
val count: StateFlow
fun increment() {
_count.value = _count.value + 1
}
}
UI側 (Jetpack Composeなど)
val viewModel = CounterViewModel()
CoroutineScope(Dispatchers.Main).launch {
viewModel.count.collect { value ->
println("カウント値: $value")
}
}
viewModel.increment() // => カウント値: 1
要点をまとめます
● MutableStateFlow で内部の状態を更新する。
● 外部には StateFlow として公開することで 読み取り専用 にできる。
LiveData との違いをついでに
Android でよく使われる LiveData と比べるとこんな違いがあります。
項目 StateFlow LiveData
初期値 必須 任意
値の保持 最新の値を保持 最新の値を保持
ライフサイクル連動 なし あり(Activity/Fragment に便利)
コルーチン連携 標準で対応 拡張ライブラリが必要
新しい Kotlin Flow ベースの開発では StateFlow を推奨しています
LiveDataは既存コードでよく使われています
どんなときに使うかというと
ViewModel で UI の状態を保持・配信 したいときや、
設定値、カウンター値、ユーザー入力などをリアルタイムで監視したいとき
複数画面・複数コンポーネントで同じ状態を共有したいときです。
つまり、StateFlow っていうのは
「最新の状態を常に保持して、必要なときに購読できる Flow」で
Jetpack Compose の UI 状態管理などでとても便利な機能です。