从T
消耗ReceiveChannel<T>
项的Android片段。消费后,T
应从ReceiveChannel<T>
删除。
我需要一个支持从中消耗物品的ReceiveChannel<T>
。它应该作为FIFO队列。
我目前从我的用户界面附加到频道,如:
launch(uiJob) { channel.consumeEach{ /** ... */ } }
我通过致电uiJob.cancel()
分离。
期望的行为:
val channel = Channel<Int>(UNLIMITED)
channel.send(1)
channel.send(2)
// ui attaches, receives `1` and `2`
channel.send(3) // ui immediately receives `3`
// ui detaches
channel.send(4)
channel.send(5)
// ui attaches, receiving `4` and `5`
不幸的是,当我从频道分离时,频道已关闭。这会导致.send(4)
和.send(5)
抛出异常,因为频道已关闭。我希望能够从频道中分离并使其保持可用状态。我怎么能这样做?
Channel<Int>(UNLIMITED)
适合我的用例完美,除了,它会在取消订阅时关闭频道。我希望频道保持开放状态。这可能吗?
答案 0 :(得分:1)
Channel.consumeEach
方法调用Channel.consume
方法,该方法在文档中包含以下内容:
通过在执行块后始终调用cancel,确保给定的块消耗给定通道中的所有元素。
因此解决方案是不使用consume[Each]
。例如,你可以这样做:
launch(uiJob) { for (it in channel) { /** ... */ } }
答案 1 :(得分:1)
您可以使用BroadcastChannel
。但是,您需要指定有限的尺寸(例如1
),UNLIMITED
和0
BroadcastChannel
(对于rendez-vous)ConflatedBroadcastChannel
不支持。
您还可以使用LiveData
,它始终为新订阅者提供最新价值,例如Fragment
正在执行的操作。
ConflatedBroadcastChannel
实例只收到最新值,这是一个大问题吗?如果没有,那么就去BroacastChannel
。否则,"Time", "Container 1", "Container 1 pressure", "Container 2", "Container 2 pressure", and so on.
s都不适合您的用例(尝试一下,看看您是否得到了您正在寻找的行为)。