Korutyny i funkcje suspend
Pisz kod asynchroniczny, który wygląda jak synchroniczny. Używaj funkcji suspend, zakresów korutyn i dispatcherów (IO, Main, Default).
Korutyny i funkcje suspend to bezpłatna lekcja Android Academy na CoddyKit. To lekcja 3 z 6. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Android Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Android Academy zawiera 6 lekcji w sumie.
Problem: blokowanie wątku interfejsu użytkownika
Android wykonuje wszystkie operacje interfejsu użytkownika w wątku głównym. Jeśli wykonają Państwo żądanie sieciowe lub odczyt bazy danych w wątku głównym, interfejs użytkownika zawiesi się do czasu zakończenia operacji.
Jeśli interfejs użytkownika pozostaje zawieszony przez ponad 5 sekund, Android wyświetla okno dialogowe ANR (App Not Responding), a użytkownik może wymusić zamknięcie aplikacji.
Czym są korutyny?
Korutyny Kotlinu umożliwiają pisanie kodu asynchronicznego, który wygląda jak sekwencyjny — bez callbacków i łańcuchów RxJava.
- Lekkie — jednocześnie może działać tysiące korutyn
- Zawieszalne — korutyna może się zatrzymać i wznowić bez blokowania wątku
- Ustrukturyzowane — respektują cykl życia (zakres)
Funkcje suspend
Funkcja oznaczona jako suspend może wstrzymać swoje wykonanie bez blokowania wątku. Można ją wywołać wyłącznie z innej funkcji suspend lub zakresu korutyny.
import kotlinx.coroutines.*
suspend fun fetchData(): String {
delay(1000) // simulates 1 second network call
return "Data loaded!"
}
fun main() = runBlocking {
println("Fetching...")
val result = fetchData() // suspends here, doesn't block
println(result) // Data loaded!
println("Done")
}Zakresy korutyn
Każda korutyna działa wewnątrz zakresu, który określa jej cykl życia:
viewModelScope— anulowany po usunięciu ViewModellifecycleScope— anulowany po zniszczeniu Activity/FragmentGlobalScope— działa bez końca (należy go unikać)runBlocking— przeznaczony wyłącznie do testów
launch a async
Istnieją dwa sposoby uruchomienia korutyny:
launch { }— uruchomienie bez oczekiwania na wynik, bez wartości zwracanejasync { }.await()— zwraca wynik, na który można zaczekać
import kotlinx.coroutines.*
fun main() = runBlocking {
// launch: no return value
launch {
delay(500)
println("launch done")
}
// async: returns a Deferred<T>
val deferred = async {
delay(300)
42
}
val result = deferred.await()
println("async result: $result")
}Dispatchers: który wątek?
Dispatchers kontrolują, na których wątkach działa korutyna:
Dispatchers.Main— wątek interfejsu użytkownika (do aktualizowania widoków)Dispatchers.IO— do operacji sieciowych i dyskowychDispatchers.Default— do zadań intensywnie korzystających z procesora
Użyj withContext(Dispatchers.IO) { }, aby przełączyć dispatcher wewnątrz korutyny.
Przykład viewModelScope
Pobieranie danych w ViewModelu bez blokowania interfejsu użytkownika:
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.*
class DataViewModel : ViewModel() {
fun loadData() {
viewModelScope.launch {
// Switch to IO thread for network
val data = withContext(Dispatchers.IO) {
// simulate network request
delay(1000)
"Result from server"
}
// Back on Main thread — safe to update UI
_uiState.value = data
}
}
}Obsługa błędów w korutynach
Wyjątki w korutynie obsługuje się za pomocą try/catch, tak samo jak w zwykłym kodzie:
viewModelScope.launch {
try {
val result = withContext(Dispatchers.IO) {
api.fetchUser() // may throw IOException
}
_user.value = result
} catch (e: Exception) {
_error.value = "Failed: ${e.message}"
}
}Korutyny równoległe
Uruchom dwa zadania równolegle i zaczekaj na zakończenie obu, używając async/await:
viewModelScope.launch {
// Both run at the same time!
val userDeferred = async(Dispatchers.IO) { api.getUser() }
val postsDeferred = async(Dispatchers.IO) { api.getPosts() }
val user = userDeferred.await()
val posts = postsDeferred.await()
_state.value = UiState(user, posts)
}Szybkie sprawdzenie
Którego dispatchera korutyn należy użyć do operacji sieciowych i bazodanowych?
Podsumowanie: korutyny
Potrafisz już pisać kod asynchroniczny bez callbacków:
suspend fun— może wstrzymać działanie bez blokowania wątkuviewModelScope.launch { }— uruchamia korutynę w ViewModeluwithContext(Dispatchers.IO)— przełącza na wątek działający w tleasync { }.await()— praca równoległa z wynikiem- try/catch działa w korutynach standardowo
Dalej: wzorzec Repository — przejrzyste oddzielenie źródeł danych.
Często zadawane pytania
Czy lekcja „Korutyny i funkcje suspend” jest bezpłatna?
Tak — pełny tekst „Korutyny i funkcje suspend” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Android Academy, przejdź na CoddyKit PRO. Kurs Android Academy zawiera 6 lekcji w sumie.
Co nauczysz się w „Korutyny i funkcje suspend”?
Pisz kod asynchroniczny, który wygląda jak synchroniczny. Używaj funkcji suspend, zakresów korutyn i dispatcherów (IO, Main, Default). Ćwiczysz Android Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Android Academy?
Nie wymagamy żadnego doświadczenia. Android Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 6.
Ile czasu zajmuje lekcja „Korutyny i funkcje suspend”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Android Academy?
Tak. Każda lekcja Android Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- ViewModel i LiveData
- Baza danych Room
- Korutyny i funkcje suspend
- Wzorzec Repository
- Navigation Component
- Wstrzykiwanie zależności z Hilt