Из корутины в Main
Есть метод, который по ссылке возвращает json геокодинг по координатам:
private fun urlRead() {
GlobalScope.launch(Dispatchers.IO) {
val lng = intent.getDoubleExtra(LAT, 0.0)
val lat = intent.getDoubleExtra(LNG, 0.0)
val apiKey = "..."
val geocodeURL = "https://geocode-maps.yandex.ru/1.x/?apikey=$apiKey&format=json&geocode=$lat,$lng"
val apiResponse = URL(geocodeURL).readText()
val txtAddressArray = getAddressLines(apiResponse)
txtAddress.setText(txtAddressArray[0])
val txtAddressAdapter = ArrayAdapter(applicationContext, R.layout.autocomplete_layout, txtAddressArray)
txtAddressAdapter.setDropDownViewResource(R.layout.autocomplete_layout)
txtAddress.setAdapter(txtAddressAdapter)
}
}
При попытке метод запустить вылезает ошибка:
Can't create handler inside thread Thread[DefaultDispatcher-worker-1,5,main] that has not called Looper.prepare()
Что значит, что нельзя из других потоков взаимодействовать с основым. Как можно исправить ситуацию?
Ответы (1 шт):
Автор решения: Crush
→ Ссылка
Нам известно, что в основном потоке выполняются операции с UI. Сетевые операции выполняем в другом потоке:
fun fetchData() : Deferred<String> {
return GlobalScope.async {
// код
URL(geocodeURL).readText()
}
}
Затем, например, в активности:
MainScope().launch {
val result = fetchData().await()
val txtAddressArray = getAddressLines(result)
txtAddress.setText(txtAddressArray[0])
// и далее обновление UI
}
Можно поступить и другим образом: передать LiveData в Вашу функцию, записать методом post данные в LiveData, в активности написать observer на LiveData и в нем обновлять UI.