阅读 100

SharedFlowBus:30行代码实现消息总线你确定不看吗

前言

最近看到很多关于livedata和flow的文章,大家都在学那我肯定不能落后。便去学习一番,偶得SharedFlowBus(卷死你们)。

那么正式开始前我们先大概了解下 StateFlowSharedFlow

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

文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐