Y&S SoftWareのホームページ
使いかってのいいソフトウェアを開発します

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 = _count.asStateFlow()

  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 状態管理などでとても便利な機能です。