为什么 CoroutineScope 内的 lambda 中的挂起函数调用会产生错误?

Ren*_*ies 5 android kotlin-coroutines

我有一个重试策略,它接受 lambda,启动 a CoroutineScope,增加重试计数器,检查是否达到最大重试次数,waitTime根据重试计数计算 a ,延迟这次的范围,最后调用 lambda:

        fun connectionRetryPolicy(block: () -> Unit) {

            Timber.d("connectionRetryPolicy: called")

            // Launch the coroutine to wait for a specific delay
            val scope = CoroutineScope(Job() + Dispatchers.Main)
            scope.launch {

                // Get and increment the current retry counter
                val counter = retryCounter.getAndIncrement()

                // Check if the counter is smaller than the maximum retry count and if so, wait a bit and execute the given function
                if (counter < maxRetry) {

                    // Calculate the time to be waited
                    val waitTime: Long = (2f.pow(counter) * baseDelayMillis).toLong()

                    // Delay the scope for the calculated time
                    delay(waitTime)

                    // Execute the given function
                    block()

                }

                // Else, throw an exception
                else {

                    throw FirebaseNetworkException("Retry count reached")

                }

            }

        }

Run Code Online (Sandbox Code Playgroud)

调用此方法以递归地调用挂起函数作为 lambda,如下所示:

    private suspend fun connectToGooglePlayBillingService(): BillingResult? {

        Timber.d("connectToGooglePlayBillingService: called")

        return suspendCoroutine { continuation ->

            // If the billingClient is not already ready, start the connection
            if (!playStoreBillingClient.isReady) {

                // Start the connection and wait for its result in the listener
                playStoreBillingClient.startConnection(object: BillingClientStateListener {

                    override fun onBillingServiceDisconnected() {

                        Timber.d("onBillingServiceDisconnected: called")

                        // Retry to connect using the RetryPolicies
                        RetryPolicies.connectionRetryPolicy { connectToGooglePlayBillingService() }

                    }

                    override fun onBillingSetupFinished(billingResult: BillingResult?) {

                        // There is code that does not matter here

                    }

                })

            }

        }

    }
Run Code Online (Sandbox Code Playgroud)

现在,Lint 告诉我,connectToGooglePlayBillingService不能在 lambda 内部调用它,因为它是一个挂起函数,需要在CoroutineScope. 正如您所看到的,我确实将 lambda 称为 a CoroutineScopein connectionRetryPolicy

这是 Lint 中的错误还是我在这里做错了什么?我知道,我可以CoroutineScope在 lambda 内部创建一个新的,然后调用connectToGooglePlayBillingService,但我不确定这在性能方面是否明智。

cor*_*her 9

代替

fun connectionRetryPolicy(block: () -> Unit)
Run Code Online (Sandbox Code Playgroud)

fun connectionRetryPolicy(block: suspend () -> Unit)
Run Code Online (Sandbox Code Playgroud)

因为您block()将在协程内运行,但其他方法不知道这一点。

  • 天哪,现在我感觉自己很愚蠢。我实际上已经尝试过这个,但在“挂起”之后添加了“乐趣”。嗯,非常感谢您的快速答复! (3认同)