Используйте собственность как принадлежность для Kotlin Coroutine - PullRequest
0 голосов
/ 01 октября 2019

Вопрос Kotlin Coroutines ... борется с использованием свойства вместо функции, являющейся аксессором асинхронного вызова.

Справочная информация - я пытаюсь использовать FusedLocationProviderClient с kotlinx-coroutines-play-servicesбиблиотека для использования метода .await() в Task вместо добавления обратных вызовов ...

В настоящее время имеется метод получения свойства, исключающий функцию приостановки, но не уверенный в том, как правильно запустить сопрограммуво избежание

необходимая единица обнаружена XYZ

ошибка ...

 val lastUserLatLng: LatLng?
        get() {
            val location = lastUserLocation
            return if (location != null) {
                LatLng(location.latitude, location.longitude)
            } else {
                null
            }
        }

    val lastUserLocation: Location?
        get() {
            GlobalScope.launch {
                return@launch getLastUserLocationAsync()  <--- ERROR HERE
            }
        }

    private suspend fun getLastUserLocationAsync() : Location? = withContext(Dispatchers.Main) {
        return@withContext if (enabled) fusedLocationClient.lastLocation.await() else null
    }

Есть мысли о том, как с этим справиться?

1 Ответ

2 голосов
/ 01 октября 2019

Свойства не могут быть асинхронными. В общем, вы не должны синхронизировать асинхронные вызовы. Вам нужно будет вернуть Deferred и вызвать await(), когда вам нужно значение.

val lastUserLatLng: Deferredd<LatLng?>
    get() = GlobalScope.async {
        lastUserLocation.await()?.run {
            LatLng(latitude, longitude)
        }
    }

val lastUserLocation: Deferred<Location?>
    get() = GlobalScope.async {
        getLastUserLocationAsync()
    }

private suspend fun getLastUserLocationAsync() : Location? = withContext(Dispatchers.Main) {
    return@withContext if (enabled) fusedLocationClient.lastLocation.await() else null
}

Но технически это возможно, хотя вы должны , а не сделать это. runBlocking() блокируется, пока значение не станет доступным, и возвращает его.

...