繁体   English   中英

从使用 Kotlin 协程调用挂起函数的普通函数返回值

[英]Returning value from normal function which called suspend function using Kotlin Coroutine

嗨,我在一个项目中使用 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”设为挂起的情况下实现?。

如果你不能让isNetworkAvailable成为一个suspend函数,那么它将是一个阻塞函数。 这意味着,任何调用isNetworkAvailable代码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) { ... }
}

(代码可能有错别字)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM