如何解决经过一定时间后关闭流
我正在尝试创建一个流程,该流程将发布发现蓝牙LE设备的结果。
扫描此类设备时,永远不会收到完成的扫描信号,因此我必须在一定时间后手动停止流量。
我目前用于实现上述目的的代码如下:
({mockScan
用于在模拟器上工作时模拟扫描,当我移至真实设备时,它将被普通扫描取代)
在我的视图模型上:
private fun startScanning() {
scanJob?.cancel() //cancel the scanning job if there is any
_devices.clear() //clear the currently discovered devices
scanJob = launch { //launch a new job
repo.startScanning(10000) //this will call the repo,it creates a flow with the results
.flowOn(dispatcher.IO)
.buffer()
.onCompletion {
scanJob = null
updateState() //this will update the screen state
}
.catch {
Timber.d("Error ${it.message}") //for now I just show the error,later I will handle it
}
.collect { //when a new entry comes
_devices.add(it) //I add it to my existing devices
devices.postValue(_devices) //and post the value to my live data which will be picked up by the adapter
}
}
updateState() //this will update the screen state
}
以及在我的存储库中
@ExperimentalCoroutinesApi
override fun startScanning(period: Long): Flow<Device> =
callbackFlow {
//this is a dummy interface I created to test scanning
val callback = object : LeScanCallback {
override fun onScanResult(callbackType: Int,result: ScanResult?) {
offer(Device(result!!.device.first!!,result.device.second!!))
}
}
mockScan(callback) //this simulates scanning
val scope = this
launch {
delay(period) //after some time cancel the scope (which should call awaitClose)
scope.cancel()
}
awaitClose {
//here I will put the code that will actually stop the scan from the adapter
Timber.d("Finished")
}
}
为完成起见,这是mockScan
方法
private fun mockScan(callback: LeScanCallback) {
launch {
launch(DispatcherImpl.IO) {
var id = 0
scanning = true
while (scanning) {
id++
delay(Random.nextInt(1,3) * 1000L)
val device = Pair("address $id","name $id")
callback.onScanResult(3,ScanResult(device))
}
}
}
}
上述情况似乎可行,并且确实在10秒钟后调用了onCompletion
函数,以便我可以清理所有需要的东西
我的问题是,是否有更好的方法来限制流可以运行的时间?还是我使用启动->延迟-> scope.close()方法卡住了?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。