Возвращает значение из нормальной функции, которая вызвала функцию приостановки, используя Kotlin Coroutine - PullRequest
0 голосов
/ 23 мая 2019

Привет! Я использую библиотеку сопрограмм Kotlin в проекте.

Приведенный ниже метод вызывает функцию suspend, которая возвращает логическое значение.

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()
                }
            }

Методы вспомогательного приостановки называются веб-службой, использующей модификацию.Поскольку это возвратило бы логическое, сделало это как синхронный вызов .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" в режиме ожидания?.

1 Ответ

0 голосов
/ 23 мая 2019

Если вы не можете сделать функцию 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) { ... }
}

(код может содержать опечатки)

...