欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Kotlin StateFlow單數(shù)據(jù)更新熱流設(shè)計(jì)與使用介紹

 更新時(shí)間:2022年09月28日 11:45:14   作者:LeeDuo.  
StateFlow當(dāng)值發(fā)生變化,就會(huì)將值發(fā)送出去,下流就可以接收到新值。在某些場(chǎng)景下,StateFlow比LiveData更適用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧

一.StateFlow的設(shè)計(jì)

StateFlow是一種單數(shù)據(jù)更新的熱流,通過(guò)emit方法更新StateFlow的數(shù)據(jù),通過(guò)value屬性可以獲取當(dāng)前的數(shù)據(jù)。在StateFlow中,核心接口的繼承關(guān)系如下圖所示:

1.StateFlow接口

StateFlow接口繼承自SharedFlow接口,代碼如下:

public interface StateFlow<out T> : SharedFlow<T> {
    // 當(dāng)前的數(shù)據(jù)
    public val value: T
}
  • 訂閱過(guò)程:在StateFlow中,每個(gè)FlowCollecter類(lèi)型的對(duì)象都被稱(chēng)為訂閱者。調(diào)用StateFlow類(lèi)型對(duì)象的collect方法會(huì)觸發(fā)訂閱。正常情況下,訂閱不會(huì)自動(dòng)結(jié)束,但訂閱者可以取消訂閱,當(dāng)訂閱者所在的協(xié)程被取消時(shí),訂閱過(guò)程就會(huì)取消。
  • 冷流轉(zhuǎn)換熱流:對(duì)于一個(gè)冷流,可以通過(guò)調(diào)用stateIn方法,轉(zhuǎn)換為一個(gè)單數(shù)據(jù)更新的熱流。
  • 相等判定:在StateFlow中,通過(guò)Any#equals方法來(lái)判斷前后兩個(gè)數(shù)據(jù)是否相等。當(dāng)前后兩個(gè)數(shù)據(jù)相等時(shí),數(shù)據(jù)不會(huì)被更新,訂閱者也不會(huì)處理。
  • 數(shù)據(jù)緩存:StateFlow必須要有一個(gè)初始值。當(dāng)新訂閱者出現(xiàn)時(shí),StateFlow會(huì)將最新的數(shù)據(jù)發(fā)射給訂閱者。StateFlow只保留最后發(fā)射的數(shù)據(jù),除此之外不會(huì)緩存任何其他的數(shù)據(jù)。同時(shí),StateFlow不支持resetReplayCache方法。
  • StateFlow并發(fā): StateFlow中所有的方法都是線程安全的,并且可以在多協(xié)程并發(fā)的場(chǎng)景中使用且不必額外加鎖。
  • 操作符使用:對(duì)StateFlow使用flowOn操作符、conflate操作符、參數(shù)為CONFLATED或RENDEZVOUS的buffer操作符、cancellable操作符是無(wú)效的。
  • 使用場(chǎng)景:使用StateFlow作為數(shù)據(jù)模型,可以表示任何狀態(tài)。
  • StateFlow與SharedFlow的區(qū)別:StateFlow是SharedFlow的一種特定方向的、高性能的、高效的實(shí)現(xiàn),廣泛的用于單狀態(tài)變化的場(chǎng)景,所有與SharedFlow相關(guān)基本規(guī)則、約束、操作符都適用于StateFlow。當(dāng)使用如下的參數(shù)創(chuàng)建SharedFlow對(duì)象,并對(duì)其使用distinctUntilChanged操作符,可以得到一個(gè)與StateFlow行為相同的SharedFlow對(duì)象:
// StateFlow
val stateFlow = MutableStateFlow(initialValue)
// 與StateFlow行為相同的SharedFlow
// 注意參數(shù)
val sharedFlow = MutableSharedFlow(
            replay = 1,
            extraBufferCapacity = 0, 
            onBufferOverflow = BufferOverflow.DROP_OLDEST)
// 設(shè)置初始值
sharedFlow.tryEmit(initialValue)
// distinctUntilChanged方法,只有當(dāng)前后發(fā)射的兩個(gè)數(shù)據(jù)不同時(shí)才會(huì)將數(shù)據(jù)向下游發(fā)射
val state = sharedFlow.distinctUntilChanged()

StateFlow與ConflatedBroadcastChannel的區(qū)別:從概念上講,StateFlow與ConflatedBroadcastChannel很相似,但二者也有很大的差別,推薦使用StateFlow,StateFlow設(shè)計(jì)的目的就是要在未來(lái)替代ConflatedBroadcastChannel:

  • StateFlow更簡(jiǎn)單,不需要實(shí)現(xiàn)一堆與Channel相關(guān)的接口。
  • StateFlow始終持有一個(gè)數(shù)據(jù),并且無(wú)論在任何時(shí)間都可以安全的通過(guò)value屬性獲取。
  • StateFlow清楚地劃分了只讀的StateFlow和可讀可寫(xiě)的StateFlow。
  • StateFlow對(duì)前后數(shù)據(jù)的比較是與distinctUntilChanged操作符類(lèi)似的,而ConflatedBroadcastChannel對(duì)數(shù)據(jù)進(jìn)行相等比較是基于標(biāo)識(shí)引用。
  • StateFlow不能關(guān)閉,也不能表示失敗,因此如果需要,所有的錯(cuò)誤與完成信號(hào)都應(yīng)該具體化。

2. MutableStateFlow接口

MutableStateFlow接口繼承自MutableSharedFlow接口與StateFlow接口,并在此基礎(chǔ)上定義了一個(gè)新方法compareAndSet,代碼如下:

public interface MutableStateFlow<T> : StateFlow<T>, MutableSharedFlow<T> {
    // 當(dāng)前數(shù)據(jù)
    public override var value: T
    // 通過(guò)CAS的方式,更新value
    // 如果except與value相等,則將value更新為update,并返回true
    // 如果except與value不相等,不做任何操作,直接返回false
    // 如果except、value、update同時(shí)相等,不做任何操作,直接返回true
    public fun compareAndSet(expect: T, update: T): Boolean
}

二.StateFlow的使用

1.MutableStateFlow方法

在協(xié)程中,可以通過(guò)調(diào)用MutableStateFlow方法創(chuàng)建一個(gè)MutableStateFlow接口指向的對(duì)象,代碼如下:

public fun <T> MutableStateFlow(value: T): MutableStateFlow<T> {
    ...
}

通過(guò)MutableStateFlow方法可以創(chuàng)建一個(gè)類(lèi)型為MutableStateFlow的對(duì)象,需要提供一個(gè)參數(shù)value,作為初始值。

在并發(fā)場(chǎng)景下調(diào)用emit方法時(shí),會(huì)使StateFlow的數(shù)據(jù)快速更新,對(duì)于處理數(shù)據(jù)慢的訂閱者,將會(huì)跳過(guò)這些快速更新的數(shù)據(jù),但當(dāng)訂閱者需要處理數(shù)據(jù)時(shí),獲取的一定是最新更新的數(shù)據(jù)。

2.使用示例

代碼如下:

private suspend fun test() {
    // 創(chuàng)建一個(gè)熱流,初始值為1
    val flow = MutableStateFlow(1)
    // 將MutableStateFlow對(duì)象轉(zhuǎn)換為StateFlow對(duì)象
    // StateFlow對(duì)象不能調(diào)用emit方法,因此只能用于接收
    val onlyReadFlow = flow.asStateFlow()
    // 接收者1
    // 啟動(dòng)一個(gè)新的協(xié)程
    GlobalScope.launch {
        // 觸發(fā)并處理接收的數(shù)據(jù)
        onlyReadFlow.collect {
            Log.d("liduozuishuai", "test1: $it")
        }
    }
    // 接收者2
    // 啟動(dòng)一個(gè)新協(xié)程
    GlobalScope.launch {
        // 訂閱監(jiān)聽(tīng),當(dāng)collect方法觸發(fā)訂閱時(shí),會(huì)首先會(huì)調(diào)onSubscription方法
        onlyReadFlow.onSubscription {
            Log.d("liduozuishuai", "test2: ")
            // 發(fā)射數(shù)據(jù):2
            // 向下游發(fā)射數(shù)據(jù):2,其他接收者收不到
            emit(2)
        }.onEach {
            // 處理接收的數(shù)據(jù)
            Log.d("liduozuishuai", "test2: $it")
        }.collect()
    }
    // 發(fā)送數(shù)據(jù):3,多次發(fā)送
    GlobalScope.launch {
        flow.emit(3)
        flow.emit(3)
        flow.compareAndSet(3, 3)
    }
}

對(duì)于上面的示例,接收者1會(huì)依次打印出:1、3,接收者2會(huì)依次打印出2、3。接收者2由于在處理onSubscription方法發(fā)射的數(shù)據(jù)2時(shí),MutableStateFlow對(duì)象內(nèi)部的數(shù)據(jù)1變成了數(shù)據(jù)3,因此在處理完數(shù)據(jù)2后,直接處理數(shù)據(jù)3。

到此這篇關(guān)于Kotlin StateFlow單數(shù)據(jù)更新熱流設(shè)計(jì)與使用介紹的文章就介紹到這了,更多相關(guān)Kotlin StateFlow內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android中ImageView無(wú)法居中的問(wèn)題解決方法

    Android中ImageView無(wú)法居中的問(wèn)題解決方法

    做UI布局,尤其是遇到比較復(fù)雜的多重LinearLayout嵌套,常常會(huì)被一些比較小的問(wèn)題困擾上半天,比如今天在使用ImageView的時(shí)候,想讓其居中顯示,可是無(wú)論怎樣設(shè)置layout_gravity屬性,都無(wú)法達(dá)到效果
    2013-06-06
  • Flutter如何完成路由攔截,實(shí)現(xiàn)權(quán)限管理

    Flutter如何完成路由攔截,實(shí)現(xiàn)權(quán)限管理

    本篇介紹了利用 Fluro 路由管理實(shí)現(xiàn)路由權(quán)限攔截的兩種方式,兩種方式各有好處,使用過(guò)程中可以根據(jù)實(shí)際情況決定使用哪一種方法。
    2021-06-06
  • Android實(shí)現(xiàn)網(wǎng)絡(luò)加載圖片點(diǎn)擊大圖后瀏覽可縮放

    Android實(shí)現(xiàn)網(wǎng)絡(luò)加載圖片點(diǎn)擊大圖后瀏覽可縮放

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)網(wǎng)絡(luò)加載圖片點(diǎn)擊大圖后瀏覽可縮放,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • flutter升級(jí)3.7.3報(bào)錯(cuò)Unable?to?find?bundled?Java?version解決

    flutter升級(jí)3.7.3報(bào)錯(cuò)Unable?to?find?bundled?Java?version解決

    這篇文章主要介紹了flutter升級(jí)3.7.3報(bào)錯(cuò)Unable?to?find?bundled?Java?version解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加
    2023-02-02
  • android圖片處理 讓圖片變成圓形

    android圖片處理 讓圖片變成圓形

    這篇文章主要為大家詳細(xì)介紹了android圖片處理的相關(guān)資料,讓圖片變成圓形,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • 簡(jiǎn)單談?wù)凙ndroid中SP與DP的區(qū)別

    簡(jiǎn)單談?wù)凙ndroid中SP與DP的區(qū)別

    Android里面的sp和dp網(wǎng)上有很多文章都談過(guò)了,但是看后總有一種意猶未盡的感覺(jué)?,F(xiàn)在我也來(lái)談?wù)刣p和sp,和大家交流一下,不對(duì)之處歡迎拍磚。
    2016-09-09
  • android gradle如何修改生成的apk名字

    android gradle如何修改生成的apk名字

    Gradle是當(dāng)前非?!皠疟钡脴?gòu)建工具,而這篇文章主要給大家介紹了關(guān)于android gradle如何修改生成的apk名字的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • Android使用BottomTabBar實(shí)現(xiàn)底部導(dǎo)航頁(yè)效果

    Android使用BottomTabBar實(shí)現(xiàn)底部導(dǎo)航頁(yè)效果

    這篇文章主要介紹了Android使用BottomTabBar實(shí)現(xiàn)底部導(dǎo)航頁(yè)效果,本文通過(guò)實(shí)例代碼結(jié)合文字說(shuō)明的形式給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2018-03-03
  • PopupWindow使用方法詳解

    PopupWindow使用方法詳解

    這篇文章主要為大家詳細(xì)介紹了PopupWindow的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Android listview與adapter詳解及實(shí)例代碼

    Android listview與adapter詳解及實(shí)例代碼

    本文主要介紹Android listview與adapter的知識(shí)詳解,這里整理了相關(guān)資料及實(shí)現(xiàn)代碼和實(shí)現(xiàn)效果圖,有興趣的小伙伴可以參考下
    2016-09-09

最新評(píng)論