Hi I am using Kotlin coroutine library in a project.
The below method calls a suspend function which return a boolean value.
fun isNetworkAvailable(context: Context?): Boolean {
//return checkNetworkReachability(context)
var isNetworkAvailable = false
GlobalScope.launch(Dispatchers.Default) {
isNetworkAvailable = GlobalScope.async<Boolean> {
checkNetwork()
}.await()
}
return isNetworkAvailable
}
Here checkNetwork is the suspend function. Before executing it the return value is passed to the caller (View/Activity). How could I achieve without making the "isNetworkAvailable" as suspend?.
Inside the checkNetwork method, to check reach-ability calling network call as like below.
private suspend fun checkNetwork() : Boolean {
val value = GlobalScope.async<Boolean> {
val isEastReachable = async { checkEastReachable() }
if (!isEastReachable.await()) {
checkWestReachable()
} else {
true
}
}
return value.await()
}
And the sub-methods are
private suspend fun checkEastReachable(): Boolean = coroutineScope {
withContext(Dispatchers.Default) {
repository.networkManager.callReachableEast()
}
}
private suspend fun checkWestReachable(): Boolean = coroutineScope {
withContext(Dispatchers.Default) {
repository.networkManager.callReachableWest()
}
}
The sub-suspend methods are calling a web service using retrofit. As it would return a boolean, I made it as an synchronous .execute() call.
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
}
}
I have gone through the below links
https://kotlinlang.org/docs/reference/coroutines/composing-suspending-functions.html
https://proandroiddev.com/async-operations-with-kotlin-coroutines-part-1-c51cc581ad33
and some more.
Repeating my question, How could I achieve without making the "isNetworkAvailable" as suspend?.
If you can't make isNetworkAvailable
a suspend
function, then it will be a blocking function. This means, any code calling isNetworkAvailable
will block as well, or you'd need to change this function's signature to have a callback instead.
First, let's look at the blocking version. There is a special coroutine-builder that is suited for bridging from the suspendable world into the regular/blocking world. It is called runBlocking
:
fun isNetworkAvailable(context: Context?): Boolean = runBlocking {
checkNetworkReachability(context)
}
...
val isAvailable = isNetworkAvailable(activity)
if (isAvailable) { ... }
...
If you'd like to change its signature and have a callback instead of a return-value:
fun CoroutineScope.isNetworkAvailable(context: Context?, callback: (Boolean) -> Unit) {
launch {
callback(checkNetworkReachability(context))
}
}
...
scope.isNetworkAvailable(activity) { isAvailable ->
if (isAvailable) { ... }
}
(code may have typos)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.