Kotlin の State Flow と Shared Flow
状態の流れ
StateFlow現在および新しい状態の更新をそのコレクターに発行する、状態ホルダーの監視可能なフローです。- コレクターに値の更新を発行する単一の更新可能なデータ値を持つ読み取り専用状態を表す SharedFlow。
- ステート フローは、Kotlin の既存の Flow ライブラリのより効率的で単純化されたバージョンになるように設計されています。主な違いは、Flow が時間の経過とともに更新できる単一の値を表すのに対し、Flow は一連の値を表すことです。
- State flow は Flow と同様の構文を使用しますが、値のストリームを発行する代わりに、プロパティを使用して更新できる単一の値を公開します
value。この値への変更は、ステート フローのすべてのオブザーバーに自動的に反映されます。 - 状態フローは、そのアクティブなインスタンスがコレクターの存在とは無関係に存在するため、ホットフローです。
- A
StateFlowは常にアクティブでメモリ内にあり、ガベージ コレクション ルートから他に参照がない場合にのみ、ガベージ コレクションの対象になります。 MutableStateFlow(value)初期値を持つコンストラクター関数を使用して、可変状態フローが作成されます。- 状態フローのすべてのメソッドはスレッドセーフであり、外部同期なしで並行コルーチンから安全に呼び出すことができます。
ステップ 1: モデル クラスを作成する
data class User(val id: Int, val name: String, val email: String)
class UserRepository {
suspend fun getUserById(userId: Int): User {
// make API call to fetch user data
val response = // make API call here
return response.toUser() // convert API response to User object
}
}
class UserViewModel(private val repository: UserRepository) : ViewModel() {
private val _user = MutableStateFlow<User?>(null)
val user: StateFlow<User?> = _user
fun getUserById(userId: Int) = viewModelScope.launch {
_user.value = repository.getUserById(userId)
}
}
class UserFragment : Fragment() {
private val viewModel: UserViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val userId = arguments?.getInt("userId") ?: throw IllegalArgumentException("userId is required")
viewModel.getUserById(userId)
viewModel.user.onEach { user ->
userTextView.text = user?.name ?: "Loading..."
emailTextView.text = user?.email ?: ""
}.launchIn(viewLifecycleOwner.lifecycleScope)
}
}
共有フロー
Kotlin では、SharedFlow複数のコレクターが単一のプロデューサーから発行された値を受け取ることを可能にするタイプのフローです。通常の はFlowコールドであり、コレクターがアタッチされたときにのみ値の放出を開始しますが、 はSharedFlowホットであり、現在および将来のすべてのコレクターがアタッチされるとすぐに値の放出を開始します。
はSharedFlow、アプリケーションの複数のコンポーネント間でデータ ストリームを共有する必要がある場合に役立ちます。たとえば、一部のデータの変更について UI の複数の部分に通知する場合などです。
class MainViewModel : ViewModel() {
private val _items = MutableSharedFlow<List<Item>>()
val items: SharedFlow<List<Item>> = _items
fun startFetchingItems() {
viewModelScope.launch {
while (true) {
val newItems = fetchItemsFromApi()
_items.emit(newItems)
delay(5000)
}
}
}
private suspend fun fetchItemsFromApi(): List<Item> {
// code to fetch items from API
}
}
class MainActivity : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
private lateinit var adapter: ItemAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView = findViewById(R.id.recyclerView)
adapter = ItemAdapter(emptyList())
recyclerView.apply {
layoutManager = LinearLayoutManager(this@MainActivity)
setHasFixedSize(true)
this.adapter = [email protected]
}
val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
lifecycleScope.launchWhenStarted {
viewModel.items.collectLatest { items ->
adapter.updateItems(items)
}
}
viewModel.startFetchingItems()
}
}
collectLatestFlowから発行された値を収集しFlow、最新の値のみに対して変換を実行できるKotlin の API の高階関数です。これはcollect、発行されたすべての値を収集するために使用される に似ていますが、collectLatest発行された最新の値のみを処理し、まだ処理されていない以前の値を無視します。
State フローと Shared フローの違い
SharedFlowとKotlin の主な違いの一部を次に示しますStateFlow。
- Mutable vs. Immutable:
StateFlowは、観測可能な単一の値を表す不変のデータ ホルダーであり、SharedFlow複数の値を発行できる可変のデータ ホルダーです。 - エラー処理:
StateFlow組み込みのエラー処理はありませんが、値を安全に出力し、ダウンストリーム コレクターにエラーを伝播できる機能SharedFlowをサポートしますtryEmit。 - バックプレッシャ処理:
StateFlow「コンフレーション」と呼ばれるバックプレッシャ戦略を使用します。これは、コレクタが追いつくには速すぎるように放出された中間値を自動的に削除します。パラメータとパラメータSharedFlowを使用して、背圧処理をよりきめ細かく制御できます。bufferonBufferOverflow - ブロードキャスト動作:
SharedFlow複数のコレクターに値をブロードキャストするように設計されていますが、StateFlow単一の値を監視するように設計されています。 - ユースケース:
StateFlowUI コンポーネントの現在の状態やデータベース内のデータなど、アプリケーション内の単一の信頼できる情報源を表すためによく使用されます。SharedFlow複数のユーザーが同じチャット ルームを監視する必要があるメッセージング アプリなど、アプリケーションの複数の部分が同じデータ ソースを監視する必要がある状況でよく使用されます。
結論
要約すると、KotlinSharedFlowと は、StateFlowAndroid アプリケーションにリアクティブ プログラミング パターンを実装するための強力なツールを開発者に提供します。
StateFlowは単一の不変値を表し、アプリ内の信頼できる唯一の情報源を表すのに理想的です。
SharedFlow可変であり、複数の値を発行できるため、複数のコレクターに値をブロードキャストするのにより適しています。
それぞれに独自の長所と短所があり、どちらを使用するかは、アプリの特定の要件によって異なります。
この記事がお役に立てば幸いです。
ご意見やご質問がございましたら、[email protected] までご連絡ください。あなたの拍手は、他の人がこの記事を見つけるのを助けるために本当に感謝しています .
コーディングのレベルアップ
私たちのコミュニティに参加してくれてありがとう!行く前に:
- ストーリーに拍手して作者をフォローしてください
- Level Up Coding の出版物のコンテンツをもっと見る
- 無料コーディング面接コース ⇒コースを見る
- フォローしてください: Twitter | リンクトイン| ニュースレター

![とにかく、リンクリストとは何ですか?[パート1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































