您好,我正在项目中使用 Kotlin 协程库。
下面的方法调用一个返回 bool 值的挂起函数。
fun isNetworkAvailable(context: Context?): Boolean {
//return checkNetworkReachability(context)
var isNetworkAvailable = false
GlobalScope.launch(Dispatchers.Default) {
isNetworkAvailable = GlobalScope.async<Boolean> {
checkNetwork()
}.await()
}
return isNetworkAvailable
}
这里的 checkNetwork 是挂起函数。在执行它之前,返回值被传递给调用者( View /Activity )。 如果不将“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()
}
}
sub-suspend 方法正在使用改造调用 Web 服务。因为它会返回一个 bool 值,所以我将其作为同步 .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
的代码也会被阻止,或者您需要更改此函数的签名以改为使用回调。
首先,让我们看一下阻塞版本。有一个特殊的协程构建器,适用于从可暂停世界桥接到常规/阻塞世界。它被称为 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) { ... }
}
(代码可能有错别字)
关于android - 使用 Kotlin Coroutine 从调用挂起函数的普通函数返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56276046/