前言
最近看到很多關(guān)于livedata和flow的文章漏益,大家都在學(xué)那我肯定不能落后蛹锰。便去學(xué)習(xí)一番,偶得SharedFlowBus
(卷死你們)绰疤。
那么正式開(kāi)始前我們先大概了解下 StateFlow
和 SharedFlow
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
SharedFlow
是 StateFlow
的可配置性極高的泛化數(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_LATEST
或DROP_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)力轨奄。
謝謝~~