Kotlin中?StateFlow?或?SharedFlow?的區(qū)別解析
StateFlow 和 SharedFlow 是 Kotlin 協(xié)程(Coroutines) 提供的兩種 響應(yīng)式數(shù)據(jù)流(Reactive Streams),用于在應(yīng)用程序中處理異步數(shù)據(jù)流,類似于 RxJava 的 Observable 或 Flowable,但更輕量且與 Kotlin 協(xié)程深度集成。
1. StateFlow(狀態(tài)流)
StateFlow 是一種 熱流(Hot Flow),它會存儲當(dāng)前的狀態(tài)值,并在狀態(tài)變化時通知所有訂閱者。
特點
- 必須有初始值(不能為空)。
- 只保留最新的值(新訂閱者會立即收到當(dāng)前值)。
- 是
SharedFlow的特殊情況(相當(dāng)于replay=1的SharedFlow)。 - 適用于 UI 狀態(tài)管理(如
ViewModel暴露 UI 狀態(tài))。
示例
// 定義 StateFlow(通常在 ViewModel 中)
private val _counterState = MutableStateFlow(0) // 初始值 0
val counterState: StateFlow<Int> = _counterState.asStateFlow()
// 更新值
fun increment() {
_counterState.value++ // 自動通知所有訂閱者
}
// 在 Activity/Fragment 中監(jiān)聽
lifecycleScope.launch {
viewModel.counterState.collect { value ->
textView.text = "Count: $value"
}
}2. SharedFlow(共享流)
SharedFlow 也是一種 熱流,但它不存儲狀態(tài),而是用于 廣播事件(如一次性事件、通知等)。
特點
- 沒有初始值(可以發(fā)送任意數(shù)量的數(shù)據(jù))。
- 可以配置緩存大小(
replay控制新訂閱者能收到多少歷史數(shù)據(jù))。 - 適用于事件總線、通知等場景(如 Toast 消息、導(dǎo)航事件)。
示例
// 定義 SharedFlow(通常在 ViewModel 中)
private val _toastEvent = MutableSharedFlow<String>() // 無初始值
val toastEvent: SharedFlow<String> = _toastEvent.asSharedFlow()
// 發(fā)送事件
fun showToast(message: String) {
viewModelScope.launch {
_toastEvent.emit(message) // 發(fā)送事件
}
}
// 在 Activity/Fragment 中監(jiān)聽
lifecycleScope.launch {
viewModel.toastEvent.collect { message ->
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
}StateFlow vs SharedFlow
| 特性 | StateFlow | SharedFlow |
|---|---|---|
| 初始值 | ? 必須有 | ? 不需要 |
| 緩存歷史數(shù)據(jù) | 僅最新值 | 可配置 (replay) |
| 適用場景 | UI 狀態(tài)管理(如 LiveData 替代) | 事件總線、通知 |
| 是否熱流 | ? 是 | ? 是 |
| 線程安全 | ? 是(協(xié)程作用域內(nèi)) | ? 是 |
因此,以下面這段代碼舉例:
/**
* 應(yīng)用中心數(shù)據(jù)變化,更新應(yīng)用中心小組件的顯示
*/
private fun WidgetSelectorViewModel.observerAppList() = coroutineScope.launch {
appWidgets.onEach { list ->
Log.d(TAG, "observerAppList setDataList")
gridAdapterApp.setDataList(list)
appItemBinding?.groupNoData?.isVisible = list.isEmpty()
}.launchIn(coroutineScope)
} 功能總結(jié):
這段代碼的主要作用是監(jiān)聽?wèi)?yīng)用小組件列表(appWidgets)的變化,每當(dāng)列表更新時:
將新列表設(shè)置給網(wǎng)格適配器(gridAdapterApp)以更新UI
根據(jù)列表是否為空來顯示或隱藏"無數(shù)據(jù)"的提示
所有這些操作都在協(xié)程中異步執(zhí)行
這是一種典型的響應(yīng)式編程模式,通過觀察數(shù)據(jù)流來自動更新UI,避免了手動刷新數(shù)據(jù)的需要。
首先是函數(shù)定義:
private fun WidgetSelectorViewModel.observerAppList() = coroutineScope.launch {- 這是一個 WidgetSelectorViewModel 的擴(kuò)展函數(shù)
- 函數(shù)是私有的(private)
- 返回一個協(xié)程啟動器(launch)
- 函數(shù)名為 observerAppList(),表示它用于觀察應(yīng)用列表
其次是函數(shù)體:
appWidgets.onEach { list ->
gridAdapterApp.setDataList(list)
appItemBinding?.groupNoData?.isVisible = list.isEmpty()
}.launchIn(coroutineScope)appWidgets可能是一個StateFlow或SharedFlow(取決于它的定義)。onEach會在每次數(shù)據(jù)變化時執(zhí)行,更新 UI。launchIn(coroutineScope)表示在指定的協(xié)程作用域內(nèi)啟動這個流。
總結(jié)
StateFlow→ 用于 UI 狀態(tài)管理(如LiveData的替代)。SharedFlow→ 用于 事件通知(如 Toast、導(dǎo)航事件)。- 兩者都是 熱流,即使沒有訂閱者也會發(fā)送數(shù)據(jù)。
- 通常結(jié)合
ViewModel+collect使用,實現(xiàn)響應(yīng)式 UI 更新。
如果你的 appWidgets 是一個應(yīng)用列表的狀態(tài),那它更適合用 StateFlow;如果是臨時事件(如刷新完成通知),則更適合 SharedFlow。
到此這篇關(guān)于Kotlin中 StateFlow 或 SharedFlow 的區(qū)別的文章就介紹到這了,更多相關(guān)Kotlin StateFlow 或 SharedFlow 的區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java filter中的chain.doFilter使用詳解
這篇文章主要介紹了Java filter中的chain.doFilter使用詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
詳解SpringCloud服務(wù)認(rèn)證(JWT)
本篇文章主要介紹了SpringCloud服務(wù)認(rèn)證(JWT),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01
Spring Boot 快速搭建微服務(wù)框架詳細(xì)教程
SpringBoot是為了簡化Spring應(yīng)用的創(chuàng)建、運(yùn)行、調(diào)試、部署等而出現(xiàn)的,使用它可以做到專注于Spring應(yīng)用的開發(fā),而無需過多關(guān)注XML的配置。本文重點給大家介紹Spring Boot 快速搭建微服務(wù)框架詳細(xì)教程,需要的的朋友參考下吧2017-09-09
使用SpringBoot整合高德地圖實現(xiàn)路線規(guī)劃功能
在日常的開發(fā)項目中,地圖服務(wù)是很多系統(tǒng)的核心能力之一,尤其是在物流、同城配送、出行導(dǎo)航等領(lǐng)域,在近期的一個項目中,需要實現(xiàn)用戶下單后,系統(tǒng)需要根據(jù)起點和終點地址,自動計算推薦路徑,所以本文給大家分享了如何使用SpringBoot整合高德地圖實現(xiàn)路線規(guī)劃功能2025-07-07

