kotlin coroutines: runBlocking in kotlin global.launch



这是关于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()
}

换句话说,您什么也不做,只会向背景线程提交阻止任务。

最新更新