Kar*_* Ve 4 android async-await kotlin 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
}
Run Code Online (Sandbox Code Playgroud)
这里的 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()
}
Run Code Online (Sandbox Code Playgroud)
子方法是
private suspend fun checkEastReachable(): Boolean = coroutineScope {
withContext(Dispatchers.Default) {
repository.networkManager.callReachableEast()
}
}
private suspend fun checkWestReachable(): Boolean = coroutineScope {
withContext(Dispatchers.Default) {
repository.networkManager.callReachableWest()
}
}
Run Code Online (Sandbox Code Playgroud)
子挂起方法正在使用改造调用 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
}
}
Run Code Online (Sandbox Code Playgroud)
我已经浏览了以下链接
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) { ... }
...
Run Code Online (Sandbox Code Playgroud)
如果您想更改其签名并使用回调而不是返回值:
fun CoroutineScope.isNetworkAvailable(context: Context?, callback: (Boolean) -> Unit) {
launch {
callback(checkNetworkReachability(context))
}
}
...
scope.isNetworkAvailable(activity) { isAvailable ->
if (isAvailable) { ... }
}
Run Code Online (Sandbox Code Playgroud)
(代码可能有错别字)
| 归档时间: |
|
| 查看次数: |
3634 次 |
| 最近记录: |