这是关于Runblocking的错误用法吗?作为" runblocking"文档说 This function should not be used from coroutine
。
此代码Snippnet来自Camerakit-android库。
fun start(facing: CameraFacing) {
GlobalScope.launch(cameraDispatcher) {
runBlocking {
lifecycleState = LifecycleState.STARTED
cameraFacing = facing
openCamera()
}
}
}
删除runblock,它无法正常工作。那么runBlocking
的意思是什么?
常规案例:使用coroutinescope代替runblocking
作为一般规则,如果您已经处于Coroutine(在暂停功能中(的上下文,则应始终偏爱暂停而不是阻止。这就是为什么,正如您指出的那样,runBlocking
的使用是从Coroutines内部拒绝的,因为它不必要地阻止了当前线程。
因此,每当您觉得在悬浮功能中需要runBlocking
时,都应该使用coroutineScope
。这是相当于 runBlocking
的暂停,因为它等待所有子女的coroutines在返回之前完成执行:
fun start(facing: CameraFacing) {
GlobalScope.launch(cameraDispatcher) {
coroutineScope {
lifecycleState = LifecycleState.STARTED
cameraFacing = facing
openCamera()
}
}
}
您的情况:缺少结构性并发?
在您的具体情况下,由于您没有runBlocking
就说"无法正常工作",所以我怀疑openCamera()
单独开始Coroutines。
开始统治的最佳实践是结构化并发。这意味着作为当前Coroutine的孩子们发起Coroutines,而不是使用GlobalScope
启动全球Coroutines。
如果openCamera()
使用GlobalScope
启动Coroutine,则除非使用runBlocking
,否则您将无法等待它完成,因为即使coroutineScope
提供了范围,也不会在调用GlobalScope.launch
时使用它。p>要清楚,什么阻止您在此处使用coroutineScope
(并且迫使您使用runBlocking
(不是 a GlobalScope.launch
,但它在调用一个函数,该函数本身使用GlobalScope.launch
(我怀疑openCamera()
在这里这样做(。
如果您真的想正确地做事:
- 将
openCamera()
和start()
声明为CoroutineScope
的扩展 - 删除所有
GlobalScope
用法,使用launch
,隐式接收器是您现在拥有的范围 - 使用
coroutineScope
而不是runBlocking
暂停
是的,这是错误的,因为它阻止了一切都必须提供的一切。这是一种更复杂和混乱的写作方式
yourJavaExecutor.submit {
lifecycleState = LifecycleState.STARTED
cameraFacing = facing
openCamera()
}
换句话说,您什么也不做,只会向背景线程提交阻止任务。