Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/235.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在一定时间后关闭流_Android_Kotlin Coroutines_Kotlin Coroutines Flow - Fatal编程技术网

Android 在一定时间后关闭流

Android 在一定时间后关闭流,android,kotlin-coroutines,kotlin-coroutines-flow,Android,Kotlin Coroutines,Kotlin Coroutines Flow,我正在尝试创建一个流,该流将发布发现蓝牙设备的结果 当扫描这样的设备时,一个人永远不会收到一个完成的扫描信号,所以我必须在一段时间后手动停止流动 我目前用于实现上述目标的代码如下: (mockScan用于在仿真器上工作时模拟扫描,当我移动到实际设备时,它将替换为正常扫描) 在我的viewmodel上: private fun startScanning() { scanJob?.cancel() //cancel the scanning job if there is any

我正在尝试创建一个流,该流将发布发现蓝牙设备的结果

当扫描这样的设备时,一个人永远不会收到一个完成的扫描信号,所以我必须在一段时间后手动停止流动

我目前用于实现上述目标的代码如下:

mockScan
用于在仿真器上工作时模拟扫描,当我移动到实际设备时,它将替换为正常扫描)

在我的viewmodel上:

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")
            }
        }
上面的场景似乎有效,实际上在10秒后调用了
onCompletion
函数,以便我可以清理任何需要的东西

我的问题是,有没有更好的方法来限制流可以运行的时间?还是我一直在使用launch->delay->scope.close()方法

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))
            }

        }
    }
}