Mam pytanie w głowie i nie wiem, jak to sprawdzić.
Załóżmy, że mam funkcję getData
, która ładuje dane z obiektu dziedziny i zajmuje to 5 sekund.
Bez coroutine muszę wywołać tę metodę w wątku w tle, aby uniknąć blokowania interfejsu użytkownika.
Jeśli zmienię getData
na wstrzymanie funkcji i wywołam to w głównym wątku, czy nadal będzie zamrażać wątek interfejsu użytkownika na 5 sekund? A może będzie to jak wywołanie delay (5000) wewnątrz funkcji getData
, czy nie zablokuje wątku interfejsu użytkownika?
Chcę utworzyć prosty projekt, aby to sprawdzić, ale nie mam wystarczająco dużych danych, aby spowodować opóźnienie o 5 sekund.
2 odpowiedzi
Jeśli zmienię funkcję
getData
nasuspend
i wywołam ją w wątku głównym, czy wątek interfejsu użytkownika nadal będzie blokowany na 5 sekund?
Tak, współprogramy nie mogą cofnąć faktu, że dany fragment kodu wykonuje wywołanie funkcji blokującej. Jest to typowy idiom, którego możesz użyć do przekazania wywołania blokującego do wątku w tle, a następnie kontynuowania pracy z nim w wątku interfejsu użytkownika:
myScope.launch {
val result = withContext(Dispatchers.IO) {
// blocking call here
}
// use the result to update the GUI here
}
Myślę, że to zależy od tego, co masz na myśli
Jeśli zmienię
getData
, aby zawiesić funkcję
- Jeśli po prostu dodasz słowo kluczowe
suspend
do funkcji, nic to nie zmieni, tj. wątek będzie blokowany do czasu otrzymania odpowiedzi. - Jeśli przepiszesz funkcję tak, aby była „zawieszona”, to będzie
- uruchom żądanie
- zawieś się (bez blokowania wątku)
- wznów po otrzymaniu odpowiedzi
Aby to osiągnąć, możesz użyć funkcji suspendCoroutine
z biblioteki Coroutines.
Abstrakcyjnym przykładem może być coś takiego jak poniżej:
suspend fun getData(): String = suspendCoroutine { continuation ->
// 1. Trigger event
serverApi.getData().onResult(
// 3. Resume either with data or error, after callback received from serverApi
onSuccess = {
continuation.resume("Data")
},
onError = {
continuation.resume("Error")
}
)
// 2. Suspend after block is finished
}
PS Prawdopodobnie w twoim przypadku (pobranie danych z db) powyższe nie zadziała, ponieważ nie ma nic do zawieszenia (funkcja jest cały czas zajęta, w przeciwieństwie do żądań sieciowych).
Podobne pytania
Nowe pytania
android
Android to mobilny system operacyjny Google, używany do programowania lub tworzenia urządzeń cyfrowych (smartfony, tablety, samochody, telewizory, Wear, Glass, IoT). W przypadku tematów związanych z Androidem użyj tagów specyficznych dla Androida, takich jak android-intent, android-activity, android-adapter itp. W przypadku pytań innych niż programowanie lub programowanie, ale związanych ze strukturą Androida, użyj tego linku: https: // android.stackexchange.com.