如何解决您可以创建一个协程BufferedBroadcastChannel来存储收到的值,即使在Android中不使用时也是如此?
我有一个图书馆,该图书馆通过从不同来源读取数据来产生值,并将其提供给可以供图书馆用户收集的流
为此,我使用此代码
private val dataChannel = BroadcastChannel<Reading>(10)
val dataFlow get() = dataChannel.asFlow()
//this may be triggered by a 5 different threads
fun newReading(type:String,value:Float,time:Date,level:Int) {
dataChannel.offer(Reading(type,value,time,Level.fromValue(level))
}
用户可以执行以下操作来获取数据
lastJob?.cancel()
lastJob = launch {
lib.dataFlow.flowOn(Dispatchers.Default).collect { reading ->
val result = processReading(reading)
withContext(Dispatchers.IO) {
Toast.makeText(application.applicationContext,result,Toast.LENGTH_LONG).show()
}
}
}
这可以按预期工作,当用户启动作业时,我的图书馆可能会继续发送数据,而图书馆的用户会继续接收数据
但是,如果用户取消了lastJob
,然后在几秒钟后再次启动它,他们将在两次之间松散我的图书馆收到的数据
有没有办法使dataChannel
在该时间段内存储通过offer
接收到的所有读数(直到其构造函数中设置的缓冲级别10),并且当dataFlow
处于活动状态时再一次发出这些值?
解决方法
您可以尝试以下一些选项:
-
BroadcastChannel<String>(Channel.BUFFERED).asFlow()
,这将使用DEFAULT_BUFFER_PROPERTY_NAME
的容量初始化您的频道,该容量默认为 64 ,但可以在JVM上覆盖。 - 您可以先创建一个
Channel(Channel.UNLIMITED)
,然后再创建consumeAsFlow()
,但是,是的,通常,拥有无限的缓冲区是不明智的做法 - 创建一个
Channel(Channel.RENDEZVOUS)
,然后使用send()
代替offer()
。集合通道基本上是容量为0的通道,每当不消耗/收集您的值时,它将暂停send()
调用。