SharedFlowBus:30行代碼實(shí)現(xiàn)消息總線你確定不看嗎

前言

最近看到很多關(guān)于livedata和flow的文章漏益,大家都在學(xué)那我肯定不能落后蛹锰。便去學(xué)習(xí)一番,偶得SharedFlowBus(卷死你們)绰疤。

那么正式開(kāi)始前我們先大概了解下 StateFlowSharedFlow

StateFlow

StateFlow 是一個(gè)狀態(tài)容器式可觀察數(shù)據(jù)流铜犬,可以向其收集器發(fā)出當(dāng)前狀態(tài)更新和新?tīng)顟B(tài)更新。還可通過(guò)其value屬性讀取當(dāng)前狀態(tài)值轻庆。

在 Android 中癣猾,StateFlow 非常適合需要讓可變狀態(tài)保持可觀察的類(lèi)。

與使用 flow 構(gòu)建器構(gòu)建的冷數(shù)據(jù)流不同余爆,StateFlow 是熱數(shù)據(jù)流:從此類(lèi)數(shù)據(jù)流收集數(shù)據(jù)不會(huì)觸發(fā)任何提供方代碼纷宇。StateFlow 始終處于活躍狀態(tài)并存于內(nèi)存中,而且只有在垃圾回收根中未涉及對(duì)它的其他引用時(shí)蛾方,它才符合垃圾回收條件像捶。

當(dāng)新使用方開(kāi)始從數(shù)據(jù)流中收集數(shù)據(jù)時(shí),它將接收信息流中的最近一個(gè)狀態(tài)及任何后續(xù)狀態(tài)转捕。您可在 LiveData 等其他可觀察類(lèi)中找到此操作行為。

SharedFlow

SharedFlowStateFlow 的可配置性極高的泛化數(shù)據(jù)流唆垃。您可以使用 SharedFlow 將 tick 信息發(fā)送到應(yīng)用的其余部分五芝,以便讓所有內(nèi)容定期同時(shí)刷新。除了獲取最新資訊之外辕万,您可能還想要使用用戶最喜歡的主題集刷新用戶信息部分枢步。

class MainViewModel :  ViewModel() {
    
    private val _sharedFlow = MutableSharedFlow<Int>(0, 1, BufferOverflow.DROP_OLDEST)
    val sharedFlow: SharedFlow<Int> = _sharedFlow

    init {
    viewModelScope.launch {
            for (i in 0..10) {
        sharedFlow.tryEmit(i)
            }
    }
    }
    
}

class MainFragment : Fragment() {

    private val viewModel: MainViewModel by viewModels()
   
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        CoroutineScope(Dispatchers.Main).launch {
            viewModel.sharedFlow.collect { 
                println(it)
            }
        }
    }

}

您可通過(guò)以下方式自定義 SharedFlow 行為:

  • 通過(guò) replay沉删,您可以針對(duì)新訂閱者重新發(fā)送多個(gè)之前已發(fā)出的值。
  • 通過(guò) onBufferOverflow醉途,您可以指定相關(guān)政策來(lái)處理緩沖區(qū)中已存滿要發(fā)送的數(shù)據(jù)項(xiàng)的情況矾瑰。默認(rèn)值為 BufferOverflow.SUSPEND,這會(huì)使調(diào)用方掛起隘擎。其他選項(xiàng)包括 DROP_LATESTDROP_OLDEST殴穴。

MutableSharedFlow 還具有 subscriptionCount 屬性,其中包含處于活躍狀態(tài)的收集器的數(shù)量货葬,以便您相應(yīng)地優(yōu)化業(yè)務(wù)邏輯采幌。MutableSharedFlow 還包含一個(gè) resetReplayCache 函數(shù),供您在不想重放已向數(shù)據(jù)流發(fā)送的最新信息的情況下使用震桶。

沒(méi)錯(cuò)休傍,以上信息摘自 Android Developers ,我真是太能水了蹲姐,干脆改行寫(xiě)小說(shuō)得了哈哈哈磨取。

SharedFlowBus的使用

// 發(fā)送消息
SharedFlowBus.with(objectKey: Class<T>).tryEmit(value: T)
// 發(fā)送粘性消息
SharedFlowBus.withSticky(objectKey: Class<T>).tryEmit(value: T)

// 訂閱消息
SharedFlowBus.on(objectKey: Class<T>).observe(owner){ it ->
    println(it)
}
// 訂閱粘性消息
SharedFlowBus.onSticky(objectKey: Class<T>).observe(owner){ it ->
    println(it)
}

通過(guò)上面的使用方法可以看出 SharedFlowBus 的優(yōu)點(diǎn)

  • 使用者不用顯示調(diào)用反注冊(cè)方法。
  • 感知生命周期柴墩,防止內(nèi)存泄漏忙厌。
  • 實(shí)時(shí)數(shù)據(jù)刷新。

SharedFlowBus的實(shí)現(xiàn)

object SharedFlowBus {

    private var events = ConcurrentHashMap<Any, MutableSharedFlow<Any>>()
    private var stickyEvents = ConcurrentHashMap<Any, MutableSharedFlow<Any>>()

    fun <T> with(objectKey: Class<T>): MutableSharedFlow<T> {
        if (!events.containsKey(objectKey)) {
            events[objectKey] = MutableSharedFlow(0, 1, BufferOverflow.DROP_OLDEST)
        }
        return events[objectKey] as MutableSharedFlow<T>
    }

    fun <T> withSticky(objectKey: Class<T>): MutableSharedFlow<T> {
        if (!stickyEvents.containsKey(objectKey)) {
            stickyEvents[objectKey] = MutableSharedFlow(1, 1, BufferOverflow.DROP_OLDEST)
        }
        return stickyEvents[objectKey] as MutableSharedFlow<T>
    }

    fun <T> on(objectKey: Class<T>): LiveData<T> {
        return with(objectKey).asLiveData()
    }

    fun <T> onSticky(objectKey: Class<T>): LiveData<T> {
        return withSticky(objectKey).asLiveData()
    }

}

源碼說(shuō)明

以上就是 SharedFlowBus 的源碼拐邪,可以直接拷貝到項(xiàng)目中使用慰毅。

最后推薦下自己的 fragmject ,一個(gè)適合初學(xué)者入門(mén)的Kotlin項(xiàng)目扎阶,通過(guò)對(duì)Kotlin的系統(tǒng)運(yùn)用汹胃,實(shí)現(xiàn)的一個(gè)功能完備符合主流市場(chǎng)標(biāo)準(zhǔn)App。雖然本項(xiàng)目的定位是入門(mén)級(jí)东臀,但是該有的知識(shí)點(diǎn)卻一點(diǎn)不少着饥,對(duì)理解其他項(xiàng)目設(shè)計(jì)思想和封裝技巧也很有幫助。

Thanks

以上就是本篇文章的全部?jī)?nèi)容惰赋,如有問(wèn)題歡迎指出宰掉,我們一起進(jìn)步。
如果喜歡的話希望點(diǎn)個(gè)贊吧赁濒,您的鼓勵(lì)是我前進(jìn)的動(dòng)力轨奄。
謝謝~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市拒炎,隨后出現(xiàn)的幾起案子挪拟,更是在濱河造成了極大的恐慌,老刑警劉巖击你,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玉组,死亡現(xiàn)場(chǎng)離奇詭異谎柄,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)惯雳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)朝巫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人石景,你說(shuō)我怎么就攤上這事劈猿。” “怎么了鸵钝?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵糙臼,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我恩商,道長(zhǎng)变逃,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任怠堪,我火速辦了婚禮揽乱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘粟矿。我一直安慰自己凰棉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布陌粹。 她就那樣靜靜地躺著撒犀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪掏秩。 梳的紋絲不亂的頭發(fā)上或舞,一...
    開(kāi)封第一講書(shū)人閱讀 51,370評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音蒙幻,去河邊找鬼映凳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛邮破,可吹牛的內(nèi)容都是我干的诈豌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼抒和,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼矫渔!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起摧莽,我...
    開(kāi)封第一講書(shū)人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤庙洼,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體送膳,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年丑蛤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了叠聋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡受裹,死狀恐怖碌补,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情棉饶,我是刑警寧澤厦章,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站照藻,受9級(jí)特大地震影響袜啃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜幸缕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一群发、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧发乔,春花似錦熟妓、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至译仗,卻和暖如春抬虽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背古劲。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工斥赋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人产艾。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓疤剑,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親闷堡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子隘膘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容