最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入探討kotlin StateFlow的兩個問題和使用場景

 更新時間:2025年08月01日 09:21:46   作者:jzlhll123  
文章探討Kotlin中LiveData與Flow的適用場景,指出LiveData適合一次性請求且避免重復觸發(fā),而StateFlow因熱流特性易導致冗余更新,建議多數(shù)場景優(yōu)先使用SharedFlow,因其無初始值、不自動去重,更靈活適配網絡請求等需求,感興趣的朋友一起看看吧

背景說明:
我們日常開發(fā)中,經常要在一個獨立的界面上做網絡請求顯示或者toast報錯,以及錯誤信息展示。
LiveData是粘性事件,如果有值(或者有初始值),再注冊監(jiān)聽,就會立刻觸發(fā)。然后就是網絡請求,將結果設置到LiveData上,等待回調。
這個流程相信是99%的開發(fā)任務。其實使用Flow我認為是殺雞用牛刀。LiveData我認為在這種場景下,是更好的選擇。因為我們99%的場景并非“流”!都是一次請求,或者下拉刷新獲取一次結果并展示,而且會屏蔽中間的快速刷新動作,避免過多請求。
好了,既然談到Flow,自然要用它來替代LiveData。

開發(fā)實踐模板規(guī)范

如下是參考開發(fā)規(guī)范做的:
首先定義一個狀態(tài)包裹類,便于后續(xù)解析和分類:

sealed class StatusState<out T> {
    object Loading : StatusState<Nothing>()
    //官方就是data class。注意有坑,后續(xù)介紹。我推薦移除data
    data class Success<out T>(val data: T) : StatusState<T>() 
    //官方就是data class。注意有坑,后續(xù)介紹。我推薦移除data
    data class Error(val message: String?) : StatusState<Nothing>()
}

第2步,在ViewModel申明;然后調用Api接口,賦值給value:

//申明為StateFlow
	private val _userInfo = MutableStateFlow<StatusState<Bean>>(StatusState.Loading)
	val userInfo: StateFlow<StatusState<Bean>> = _userInfo.asStateFlow()
	fun requestXXX(xxx) {
    	viewModelScope.launch {
	        try {
	        val data = Api.request(xx)
	        _userInfo.value = StatusState.Success(data)
	    } catch (e: Exception) {
	        _userInfo.value = StatusState.Error(e.message)
	    }
    }
}

第3步,在Fragment/Activity中collect,如下的 lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) {}}套路也是官方推薦的:

onCreate() {
       lifecycleScope.launch {
         repeatOnLifecycle(Lifecycle.State.STARTED) {
             viewModel.userInfo.collect{
                 //解析為正確
				//...ShowDialog()
				// 解析為error
				//...toast(exMsg)
             }
         }
        }
 	}

坑來了

1. 每次onStart就觸發(fā)一次

比如跳轉到下一頁返回,或者Home鍵再返回。立刻就觸發(fā)。像我這里一回來toast一下,不太合適吧?
為什么會這樣:

  • 理解collect{}函數(shù):
    • 研究了函數(shù)代碼,可以理解為一個死循環(huán),等待協(xié)程喚醒(誰?當然是我們flow發(fā)生數(shù)據變化);喚醒一次執(zhí)行一次你的collect的代碼。然后,進入下一次等待。
  • 理解repeatOnLifecycle(Lifecycle.State.STARTED):
    • 當生命周期離開STARTED即onStop的時候,把collect這個執(zhí)行死循環(huán)給cancel掉了。然后,當STARTED即onStart的時候,立刻觸發(fā)collect{}動作,死循環(huán)又回來了。

這就是repeatOnLifecycle(Life...START) + flow collect的原理。

  • 再看StateFlow的總結特性,“熱流”屬性,始終持有最新狀態(tài)值(通過 value 屬性)。
  • 新訂閱者立即獲取最新值:當收集重新啟動時(進入 STARTED),StateFlow 會立即將當前最新值(value)發(fā)送給收集器,即使該值之前已發(fā)送過。

這就導致了它的觸發(fā)。但往往我們不需要這種特性。

2. 數(shù)據相同不觸發(fā)

總結圖中有說了,自動去重,連續(xù)相同值不會觸發(fā)更新。雖然你的網絡請求已經執(zhí)行,用戶手都點麻了,但是就是不觸發(fā)collect。按道理來講,相同的網絡結果,也就你點了幾次,就彈幾次,不然瘋狂刷新沒個反饋,不好吧?

而且明明我每次都是新建的對象呀,為什么也不更新?

//網絡請求結果設置
	_userInfo.value = StatusState.Error(it.msg)

這又是另外一個坑,原因在于,data class會自行實現(xiàn)equals各個字段比較,相同就不觸發(fā)collect。因此當我改成不使用data class,那么他每次比較的是2個對象的地址,自然是不一樣的。這與LiveData 或者 SharedFlow是有區(qū)別的,liveData允許使用重復的對象。

怎么解決

使用SharedFlow。

首先它沒有初始值。并且,它不會相同對象或者equals相同就不更新,就可以使用data class。
而且每次重新collect的時候,并無緩存(你不修改MutableSharedFlow申明參數(shù)),也就不會觸發(fā)。
我想SharedFlow才是替代LiveData的真正最佳對象。

總結

回歸我前面說的,我們真的需要使用StateFlow嗎?
我想我們在99%普通頁面上的需求的時候,應該優(yōu)先需要的是SharedFlow。

到此這篇關于kotlin StateFlow的兩個問題和使用場景探討的文章就介紹到這了,更多相關kotlin StateFlow使用內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Android Dialog仿ios9中UIAlertController控件

    Android Dialog仿ios9中UIAlertController控件

    這篇文章主要為大家詳細介紹了Android Dialog仿ios9中UIAlertController控件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • 基于Android應用中如何反饋Crash報告的詳解

    基于Android應用中如何反饋Crash報告的詳解

    本篇文章是對在Android應用中如何反饋Crash報告的詳細分析介紹。需要的朋友參考下
    2013-05-05
  • Android Studio的中文亂碼問題解決方法

    Android Studio的中文亂碼問題解決方法

    Android Studio安裝后發(fā)現(xiàn)所有的中文,不管是界面上的還是輸出的log中的中文都變成小框框,具體的解決方法如下,感興趣的朋友可以參考下哈
    2013-06-06
  • Android Studio中的Gradle依賴深入講解

    Android Studio中的Gradle依賴深入講解

    Android Studio由于使用了gradle的進行項目構建,使我們開發(fā)app方便很多,下面這篇文章主要給大家介紹了關于Android Studio中Gradle依賴的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2018-09-09
  • Android串口操作方法實例

    Android串口操作方法實例

    這篇文章主要介紹了Android串口操作方法實例,本文共分5個步驟講解了Android串口操作方法,并給出代碼實例,需要的朋友可以參考下
    2015-04-04
  • Android拍照上傳功能示例代碼

    Android拍照上傳功能示例代碼

    這篇文章主要介紹了Android拍照上傳功能用法,結合實例形式詳細分析了Android拍照上傳功能所涉及的相關知識點與功能實現(xiàn)技巧,需要的朋友可以參考下
    2016-08-08
  • Android自定義view實現(xiàn)拖拽選擇按鈕

    Android自定義view實現(xiàn)拖拽選擇按鈕

    這篇文章主要為大家詳細介紹了Android自定義view實現(xiàn)拖拽選擇按鈕,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Android SharedPreferences存儲用法詳解

    Android SharedPreferences存儲用法詳解

    這篇文章主要為大家詳細介紹了Android SharedPreferences存儲用法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • Android編寫2048小游戲

    Android編寫2048小游戲

    這篇文章主要為大家詳細介紹了利用Android編寫一個2048小游戲,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • 詳解Android開發(fā)中Activity的四種launchMode

    詳解Android開發(fā)中Activity的四種launchMode

    這篇文章主要介紹了Android開發(fā)中Activity的四種launchMode,launchMode主要用于控制多個Activity間的跳轉,需要的朋友可以參考下
    2016-03-03

最新評論

团风县| 三都| 永康市| 航空| 集安市| 台安县| 甘南县| 九台市| 平原县| 葫芦岛市| 青田县| 晋城| 佛坪县| 亚东县| 隆回县| 镇赉县| 措美县| 蒙山县| 北安市| 澄城县| 廉江市| 清流县| 洛川县| 镇江市| 泸州市| 溧水县| 西乡县| 松原市| 神农架林区| 中方县| 乌苏市| 德清县| 大新县| 碌曲县| 神池县| 无棣县| 南溪县| 合作市| 罗城| 望奎县| 麻城市|