从正常函数返回值,该函数使用Kotlin Coroutine调用了暂停函数

时间:2019-05-23 13:12:00

标签: android kotlin async-await kotlin-coroutines coroutinescope

嗨,我在一个项目中使用Kotlin协程库。

下面的方法调用一个暂停函数,该函数返回一个布尔值。

fun isNetworkAvailable(context: Context?): Boolean {
            //return checkNetworkReachability(context)
            var isNetworkAvailable = false
            GlobalScope.launch(Dispatchers.Default) {
                isNetworkAvailable = GlobalScope.async<Boolean> {
                    checkNetwork()

                }.await()
            }
            return isNetworkAvailable

        }

这里checkNetwork是挂起功能。在执行它之前,返回值将传递给调用方(视图/活动)。 在不将“ isNetworkAvailable”设置为挂起状态的情况下如何实现?

在checkNetwork方法内部,如下所示检查可达性呼叫网络呼叫。

private suspend fun checkNetwork() : Boolean {
            val value = GlobalScope.async<Boolean> {
                val isEastReachable = async { checkEastReachable() }
                if (!isEastReachable.await()) {
                    checkWestReachable()
                } else {
                    true
                }
            }

            return value.await()
        }

子方法是

private suspend fun checkEastReachable(): Boolean = coroutineScope {

                withContext(Dispatchers.Default) {
                    repository.networkManager.callReachableEast()
                }
            }



private suspend fun checkWestReachable(): Boolean = coroutineScope {

                withContext(Dispatchers.Default) {
                    repository.networkManager.callReachableWest()
                }
            }

使用改型将子挂起方法称为Web服务。它将返回布尔值,使其成为同步的.execute()调用。

fun callReachableEast(): Boolean {
        return try {
            val requestCall =
                ApiService.create("eastApi").getReachabilityEast()
            requestCall.execute().isSuccessful
        } catch (exception: Exception) {
            false
        }
    }

    fun callReachableWest(): Boolean {
        return try {
            val requestCall =
                ApiService.create("westApi").getReachabilityWest()
            return requestCall.execute().isSuccessful
        } catch (exception: Exception) {
            false
        }
    }

我已经通过以下链接

https://kotlinlang.org/docs/reference/coroutines/composing-suspending-functions.html

https://proandroiddev.com/async-operations-with-kotlin-coroutines-part-1-c51cc581ad33

还有更多

重复我的问题,如何在不将“ isNetworkAvailable”设置为挂起的情况下实现?

1 个答案:

答案 0 :(得分:0)

如果您无法将isNetworkAvailable设为suspend函数,则它将成为阻塞函数。这意味着,任何调用isNetworkAvailable的代码也会被阻止,或者您需要更改此函数的签名以具有回调。

首先,让我们看一下阻止版本。有一个特殊的协程构建器,适合从可悬挂的世界过渡到常规/阻塞世界。它称为runBlocking

fun isNetworkAvailable(context: Context?): Boolean = runBlocking {
    checkNetworkReachability(context)
}

...

val isAvailable = isNetworkAvailable(activity)
if (isAvailable) { ... }
...

如果您想更改其签名并使用回调而不是返回值:

fun CoroutineScope.isNetworkAvailable(context: Context?, callback: (Boolean) -> Unit) { 
    launch {
        callback(checkNetworkReachability(context))
    }
}

...
scope.isNetworkAvailable(activity) { isAvailable ->
    if (isAvailable) { ... }
}

(代码可能有错别字)