SharedFlowBus:30行代码实现消息总线你确定不看吗
前言
最近看到很多关于livedata和flow的文章,大家都在学那我肯定不能落后。便去学习一番,偶得SharedFlowBus
(卷死你们)。
那么正式开始前我们先大概了解下 StateFlow
和 SharedFlow
StateFlow
StateFlow
是一个状态容器式可观察数据流,可以向其收集器发出当前状态更新和新状态更新。还可通过其value属性读取当前状态值。
在 Android 中,StateFlow
非常适合需要让可变状态保持可观察的类。
与使用 flow
构建器构建的冷数据流不同,StateFlow
是热数据流:从此类数据流收集数据不会触发任何提供方代码。StateFlow
始终处于活跃状态并存于内存中,而且只有在垃圾回收根中未涉及对它的其他引用时,它才符合垃圾回收条件。
当新使用方开始从数据流中收集数据时,它将接收信息流中的最近一个状态及任何后续状态。您可在 LiveData
等其他可观察类中找到此操作行为。
SharedFlow
SharedFlow
是 StateFlow
的可配置性极高的泛化数据流。您可以使用 SharedFlow
将 tick 信息发送到应用的其余部分,以便让所有内容定期同时刷新。除了获取最新资讯之外,您可能还想要使用用户最喜欢的主题集刷新用户信息部分。
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) } } } } 复制代码
您可通过以下方式自定义 SharedFlow
行为:
通过
replay
,您可以针对新订阅者重新发送多个之前已发出的值。通过
onBufferOverflow
,您可以指定相关政策来处理缓冲区中已存满要发送的数据项的情况。默认值为BufferOverflow.SUSPEND
,这会使调用方挂起。其他选项包括DROP_LATEST
或DROP_OLDEST
。
MutableSharedFlow
还具有 subscriptionCount
属性,其中包含处于活跃状态的收集器的数量,以便您相应地优化业务逻辑。MutableSharedFlow
还包含一个 resetReplayCache
函数,供您在不想重放已向数据流发送的最新信息的情况下使用。
没错,以上信息摘自 Android Developers ,我真是太能水了,干脆改行写小说得了哈哈哈。
SharedFlowBus的使用
// 发送消息 SharedFlowBus.with(objectKey: Class<T>).tryEmit(value: T) // 发送粘性消息 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) } 复制代码
通过上面的使用方法可以看出 SharedFlowBus
的优点
使用者不用显示调用反注册方法。
感知生命周期,防止内存泄漏。
实时数据刷新。
SharedFlowBus的实现
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() } } 复制代码
源码说明
以上就是 SharedFlowBus
的源码,可以直接拷贝到项目中使用。
最后推荐下自己的 fragmject ,一个适合初学者入门的Kotlin项目,通过对Kotlin的系统运用,实现的一个功能完备符合主流市场标准App。虽然本项目的定位是入门级,但是该有的知识点却一点不少,对理解其他项目设计思想和封装技巧也很有帮助。
Thanks
以上就是本篇文章的全部内容,如有问题欢迎指出,我们一起进步。 如果喜欢的话希望点个赞吧,您的鼓励是我前进的动力。 谢谢~~
作者:miaowmiaow
链接:https://juejin.cn/post/7028067962200260615