可以用多个收集器收集的 Kotlin 流(或类似的东西)
Posted
技术标签:
【中文标题】可以用多个收集器收集的 Kotlin 流(或类似的东西)【英文标题】:Kotlin flow (or something similar) that can be collected with multiple collectors 【发布时间】:2020-08-12 19:41:24 【问题描述】:我尝试使用 Kotlin Flow 作为某种消息容器,它应该将此消息传递给所有观察者(收集器)。我不想故意使用 LiveData,因为它需要了解生命周期。
不幸的是,我注意到如果一个收集器从流中收集消息,其他人就无法接收它。
我可以用什么来实现“一个输入 - 多个输出”。
【问题讨论】:
听起来你想要的是SharedFlow
。
你可能是对的,但不幸的是,它似乎还没有出现在官方实施中:/
【参考方案1】:
您可以使用 StateFlow 或 SharedFlow,它们是 Flow API,使流能够以最佳方式发出状态更新并向多个消费者发出值。
来自文档,可用here:
StateFlow:是一个状态持有者可观察流,它向其收集器发出当前和新的状态更新。当前状态值也可以通过其 value 属性读取。
SharedFlow:一个热流,它向从它收集的所有消费者发出值。 SharedFlow 是 StateFlow 的高度可配置泛化。
使用状态流和视图模型的简单示例:
class myViewModel() : ViewModel()
val messageStateFlow = MutableStateFlow("My inicial awesome message")
您可以使用某个范围发出新值:
yourScope.launch
messageStateFlow.emit("My new awesome message")
您可以使用某个范围收集值:
yourScope.launch
messageStateFlow.collect
// do something with your message
注意:切勿直接从启动或 launchIn 扩展函数从 UI 收集流来更新 UI。即使视图不可见,这些函数也会处理事件。您可以按照文档建议使用 repeatOnLifecycle。
【讨论】:
【参考方案2】:您可以尝试来自 rxJava 的 BehaviorSubject
。使用起来比糟糕的 kotlin.flow 更舒服。似乎此链接适合您:BehaviorSubject vs PublishSubject
val behaviorSubject = BehaviorSubject.create<MyObject>
// for example you can emit new item with it.onNext(),
// finish with error like it.onError() or just finish with it.onComplete()
somethingToEmit()
behaviorSubject.subscribe
somethingToHandle()
【讨论】:
以上是关于可以用多个收集器收集的 Kotlin 流(或类似的东西)的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin 协程Flow 流组合 ( Flow#zip 组合多个流 | 新组合流的元素收集间隔与被组合流元素发射间隔的联系 )
Kotlin 协程Flow 异步流 ⑥ ( 调用 Flow#launchIn 函数指定流收集协程 | 通过取消流收集所在的协程取消流 )
Kotlin 协程Flow 异步流 ⑥ ( 调用 Flow#launchIn 函数指定流收集协程 | 通过取消流收集所在的协程取消流 )