[英]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.