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

标签 android kotlin-coroutines

我有一个重试策略,它接受一个 lambda,启动一个 CoroutineScope ,增加重试计数器,检查是否达到最大重试次数,计算 waitTime根据重试次数,延迟这次的作用域,最后调用 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")

                }

            }

        }


调用此方法以递归调用挂起函数作为 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

                    }

                })

            }

        }

    }

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

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

最佳答案

代替

fun connectionRetryPolicy(block: () -> Unit)


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

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

关于android - 为什么在 CoroutineScope 内的 lambda 中调用挂起函数会产生错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62060646/

相关文章:

android - 在 AsyncTask 中测试一个涉及监听器回调的类

android - 向一定半径内的人发送通知

java - 如何获取联系人号码的组ID(Android)

kotlin - 为什么不使用 GlobalScope.launch?

android - 如何使用通知图标修复小米特定的 RemoteServiceException?

android - 如何在使用 React Native 时实现 SSL 证书锁定

android - 协程中的自定义拦截器

android - 如何使用 Kotlin Coroutines 使 setOnClickListener 去抖动 1 秒?

kotlin - 为每个函数指定 Kotlin 协程上下文还是将其留给调用者函数?推荐哪一款?

Android - 使用改造和协程获取响应状态代码