0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

📝 StateFlowとSharedFlow、どう使い分ける?(Kotlinコルーチン)(Android開発編)

Last updated at Posted at 2025-10-01

はじめに

Androidアプリを作るとき、画面に表示するデータや、ユーザーがボタンを押したといった「イベント」を、プログラムの中でスムーズにやり取りする仕組みが必要です。

Kotlinコルーチンという技術には、そのための便利なツールとして「StateFlow(ステートフロー)」と「SharedFlow(シェアードフロー)」があります。

これらはどちらも「ホットフロー」と呼ばれる種類です。
データフローの比較.png

💡 ホットフローとは?(ラジオ放送の例)

「ホットフロー」とは、聴く人(コレクタ/購読者)がいるかどうかに関係なく、常に情報を発信し続けているデータの流れのことです。まるで、放送局が24時間常に電波を出し続けているラジオ放送のようなものです。

これに対して「コールドフロー」(通常のFlow)は、誰かが「聴き始めます」と言って初めて放送を開始します。

StateFlowとSharedFlowは、この「常に流れている」データをアプリのあちこちに共有するために使われます。


1. StateFlow:常に最新を示す「スコアボード」

StateFlowは、アプリの**「今の状態」**を伝えることに特化した仕組みです。

例えるなら、**スポーツ試合の「スコアボード」**です。

特徴(スコアボードのルール)

特徴 スコアボードでの役割 根拠となる情報
常に値を持つ 試合開始時(アプリ起動時)から「0対0」など、必ず初期値が表示されています StateFlowは初期値をコンストラクタで渡す必要があります。
最新の値だけ 10点が連続で入っても、画面が更新されるのは最終的な最新の点数だけです。 StateFlowは現在の値をvalueプロパティで取得できます。
同じ値を無視 スコアが「5対5」のまま変わらない場合、ボードは何度も「5対5」を再表示しません。 連続する同じ値は無視されます (distinctUntilChangedと同じ仕組み)。

StateFlowの使いどころ

StateFlowは、画面に表示すべきデータ、つまりUIの状態を管理するために最適です。

  • 例: ニュース記事のリスト、読み込み中の表示(ローディングスピナー)、現在のエラーメッセージなど。
  • メリット: 画面の向きを変える(設定変更)などがあっても、常に最新の状態をUIに保つことができます。

2. SharedFlow:一度きりの「イベントのピストル」

SharedFlowは、StateFlowよりも自由度の高い仕組みで、主に**「何か出来事(イベント)が起こった」**ことを複数の場所に伝える役割を持ちます。

例えるなら、**運動会のスタートで鳴らす「ピストル」**です。

特徴(ピストルの合図のルール)

特徴 ピストルの役割 根拠となる情報
状態を持たない ピストルが鳴る前に「今の音」は存在しません。 SharedFlow初期値を必要としません
イベントを伝える 「パン!」という音が鳴ったら、その瞬間にイベントが送られます。 主に画面遷移やトースト表示などのワンショットイベントに使われます。
同じ値も区別できる (設定次第で) 「パン!パン!」と連続で鳴ったら、それを2つのイベントとして処理できます。 StateFlowと異なり、連続する同じ値も放出可能です。
高度な設定 新しい人が途中から聞きに来ても、直前のイベントを何個か教えてあげる(リプレイ機能)など、細かく設定できます。 replayextraBufferCapacityなどの設定が可能です。

SharedFlowの使いどころ

SharedFlowは、一度だけ実行すれば完了するアクションを複数のコンポーネントに通知したい場合に最適です。

  • 例: ユーザーがボタンをクリックした。画面の下にメッセージ(トーストやスナックバー)を一瞬だけ表示したい。ある画面から別の画面へ移動する(ナビゲーション)。
  • メリット: UIのイベント処理を一元化し、コードの可読性を向上させることができます。

3. まとめ:StateFlowとSharedFlowの使い分け

StateFlowは、SharedFlowが「最新の1つだけをリプレイし」「初期値を持ち」「連続した同じ値を無視する」という設定に固定され、最適化された状態特化型のFlowです。

目的 StateFlow (スコアボード) SharedFlow (ピストル/イベント)
何を表すか 現在の状態。常に最新の値だけ。 瞬間的な出来事(イベント)
初期値 必須 不要(デフォルト)。
同じ値が連続 無視される(UIの無駄な更新を防ぐ)。 通常放出される(イベントは発生した回数分必要)。
主な用途 UIの状態管理 (画面に表示するデータ)。 ワンショットイベント (ナビゲーション、トースト表示)。

Androidアーキテクチャにおける流れ

Androidの推奨アーキテクチャでは、ViewModelがUI層とデータ層の間に位置し、UIの状態を管理する重要な役割を担います。

  1. データ層: データソース(データベースやネットワーク通信)は、SharedFlowや通常のFlowを使ってデータを流すことがあります。
  2. ViewModel: ここで流れてきたデータを、UIが扱いやすいように**StateFlow**に変換し、UIに公開します。
    • この変換にはstateInという便利な機能が使われます。
  3. UI層(画面): UIはStateFlowを監視し、値が変わるたびに画面を更新します。

⚠️ 大事な注意点:安全な使い方

StateFlowSharedFlowをAndroidのUI(画面)で使うとき、画面が裏に隠れても(STOPPED状態になっても)データの収集(collect)を止め忘れると、アプリが無駄な動きをしたり、クラッシュしたりする可能性があります。

これを防ぐため、Androidでは画面のライフサイクル(生存期間)に合わせて、repeatOnLifecycleflowWithLifecycle といった安全な方法でフローを収集することが強く推奨されています

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?