可以用多个收集器收集的 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】:

您可以使用 StateFlowSharedFlow,它们是 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 函数指定流收集协程 | 通过取消流收集所在的协程取消流 )

Kotlin/Native 垃圾收集器如何在 C 中工作?

Kotlin 协程Flow 异步流 ③ ( 冷流 | 流被收集时运行 | 流的连续性 )

Kotlin 协程Flow 异步流 ③ ( 冷流 | 流被收集时运行 | 流的连续性 )