Coroutines (korutiny) jsou lehká vlákna Kotlinu pro asynchronní programování dostupná prostřednictvím knihovny kotlinx.coroutines. Podle JetBrains Kotlin Documentation, 2026 umožňují Coroutines pozastavit provádění funkce bez blokování vlákna, na rozdíl od tradičních Thread. Korutiny běží na omezeném fondu vláken, což je činí tisíckrát lehčími než nativní vlákna. Kotlin Coroutines jsou plně integrovány s Android Jetpack, Retrofit, Room a dalšími populárními knihovnami ekosystému Android.
Hlavní body
Coroutines (korutiny) jsou mechanismus asynchronního programování v Kotlinu, implementovaný v knihovně kotlinx.coroutines. Na rozdíl od vláken operačního systému nejsou korutiny vázány na konkrétní vlákno: mohou se pozastavit na jednom vlákně a obnovit na jiném. Jedno vlákno může provádět tisíce korutin a přepínat mezi nimi s minimální režií.
Korutiny se objevily v Kotlin 1.3 (2018) jako experimentální funkce a staly se stabilními v Kotlin 1.5 (2021). Coroutines řeší problém callback hell podobně jako async/await, ale nabízejí bohatší API: kanály (Channel), Flow, zpracování výjimek v hierarchii Job a přímou integraci s Android Lifecycle.
Podle JetBrains (2025) spotřebovává každá korutina přibližně 100 bajtů paměti oproti 1+ MB pro nativní vlákno. To umožňuje spouštět miliony korutin v jedné aplikaci bez rizika OutOfMemoryError. Právě lehkost korutin z nich dělá preferovaný nástroj pro asynchronnost v Androidu.
Každá korutina Kotlinu je zkompilována do stavového automatu pomocí Continuation Passing Style (CPS). Kompilátor přidává skrytý parametr Continuation ke každé suspend funkci. Continuation obsahuje bod obnovení a všechny lokální proměnné. Když se korutina pozastaví, runtime uloží Continuation, a když se obnoví, obnoví jej na jakémkoli dostupném vlákně z fondu Dispatcher.
suspend — klíčové slovo Kotlinu označující funkci jako pozastavitelnou. Takovou funkci lze volat pouze z jiné suspend funkce nebo z korutiny. Uvnitř suspend funkce lze volat další suspend funkce v libovolném pořadí a každý bod volání je potenciální bod pozastavení.
Mechanika je jednoduchá: když suspend funkce volá jinou suspend funkci, pozastaví se v tomto bodě a uvolní vlákno. Po dokončení volané funkce runtime pokračuje v provádění z uloženého místa. Tomu se říká cooperative cancellation — žádné vlákno není blokováno.
Důležité: suspend funkce není ve výchozím nastavení asynchronní. Pořadí provádění zůstává sekvenční, pokud se nepoužije launch nebo async. suspend pouze umožňuje funkci být pozastavena bez blokování vlákna a být součástí kontextu korutiny. Continuation Passing Style je kompilační model, ve kterém každá suspend funkce obdrží skrytý callback Continuation a kompilátor vygeneruje stavový automat pro správu pozastavení a obnovení.
CoroutineScope je kontext definující životní cyklus korutin. Všechny korutiny musí být spuštěny uvnitř scope. Když je scope zrušen (např. při ukončení Activity), všechny jeho podřízené korutiny jsou automaticky zrušeny. To zabraňuje únikům úloh na pozadí. Android Jetpack poskytuje hotové scopes pro každou komponentu: viewModelScope pro ViewModel a lifecycleScope pro Activity a Fragment, které se automaticky ruší při zničení příslušné komponenty.
Structured Concurrency — princip zaručující, že korutina neskončí, dokud neskončí všechny její podřízené korutiny. Hierarchie Job tvoří strom: kořenová korutina vytváří parent job, podřízené vytvářejí child jobs. Zrušení parent job se šíří na všechny děti. Structured Concurrency je zásadní rozdíl mezi korutinami a vlákny.
| Scope | Kde se používá | Zrušení |
|---|---|---|
| GlobalScope | Pouze pro úlohy daemon | Neruší se automaticky |
| viewModelScope | Android ViewModel | Při čištění ViewModel |
| lifecycleScope | Android Activity/Fragment | Při zničení lifecycle |
| coroutineScope | Uvnitř suspend funkce | Při zrušení parent job |
Běžný Job při chybě jedné podřízené korutiny ruší všechny siblings. SupervisorJob je výjimka: selhání jedné podřízené korutiny neovlivní ostatní. To je důležité, když několik nezávislých úloh běží paralelně a jedna může selhat, aniž by bylo nutné rušit ostatní.
Dispatchers určují, na kterých vláknech se korutiny provádějí. Dispatchers.Main — hlavní UI vlákno Androidu. Dispatchers.IO — fond pro blokující operace (síť, disk). Dispatchers.Default — pro úlohy náročné na CPU. Dispatchers.Unconfined — startuje v aktuálním vlákně, ale nezaručuje, že na něm zůstane. Správný výběr Dispatcher je kritický pro výkon: úloha IO na Default zablokuje fond pro výpočty, zatímco úloha CPU na IO vytvoří zbytečná vlákna.
withContext — funkce pro přepínání Dispatcher uvnitř korutiny. Například suspend funkce parsující JSON může přepnout na Dispatchers.Default během výpočtu a vrátit se na Dispatchers.Main pro aktualizaci UI. withContext je nejpoužívanější stavitel ve vývoji pro Android.
launch — spouští korutinu, vrací Job, nevrací výsledek (fire-and-forget). async — spouští korutinu, vrací Deferred, ze kterého lze získat výsledek pomocí await. runBlocking — blokuje aktuální vlákno pro provádění korutiny (pouze pro testy a main funkce). Výběr stavitele závisí na scénáři: launch je vhodný pro události a aktualizace, async pro úlohy s výsledkem, runBlocking pouze pro testy nebo vstupní body.
Podívejme se na tři praktické scénáře: základní korutina s launch, paralelní volání s async a zpracování chyb s SupervisorJob.
viewModelScope.launch spouští korutinu v kontextu ViewModel. Při čištění ViewModel je korutina automaticky zrušena.
class ProfileViewModel : ViewModel() {
fun loadUser() {
viewModelScope.launch(Dispatchers.IO) {
val user = api.fetchUser()
withContext(Dispatchers.Main) {
showUser(user)
}
}
}
}
coroutineScope s async spouští tři požadavky paralelně. Výsledky se shromažďují pomocí .await(). Pokud některý požadavek selže, všechny jsou zrušeny.
suspend fun loadDashboard(): Dashboard = coroutineScope {
val user = async { api.fetchUser() }
val posts = async { api.fetchPosts() }
val stats = async { api.fetchStats() }
Dashboard(user.await(), posts.await(), stats.await())
}
SupervisorJob umožňuje každé korutině dokončit se nezávisle. Chyba v jednom požadavku neruší ostatní.
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
scope.launch {
try { api.fetchUsers() } catch (e: Exception) { log(e) }
}
scope.launch {
try { api.fetchPosts() } catch (e: Exception) { log(e) }
}
Vlákna (Thread) — primitiv operačního systému. Každé vlákno má vlastní zásobník (~1 MB) a vyžaduje systémové volání pro vytvoření a přepnutí. Korutiny — jazykový primitiv, nezávislý na OS. Používají Continuation k ukládání stavu a přepínají na úrovni runtime bez systémových volání.
Podle Google (2025) snižuje použití korutin místo vláken spotřebu paměti pro úlohy na pozadí v aplikacích pro Android o 90–95%. Všechny moderní knihovny pro Android (Retrofit, Room, WorkManager) mají vestavěnou podporu pro korutiny prostřednictvím suspend funkcí. Ktor (HTTP klientský framework JetBrains) je také plně postaven na korutinách a poskytuje suspend-funkce pro každý požadavek bez callback API. Room podporuje korutiny prostřednictvím suspend-funkcí v DAO, což umožňuje provádět databázové dotazy bez blokování hlavního vlákna.
Vlákna zůstávají nezbytná pro nativní kód přes JNI, blokující volání náročná na CPU bez časového omezení (renderování videa, simulace) a při integraci s knihovnami C. Pro všechno ostatní — korutiny.
Často kladené otázky
Korutina — pozastavitelná jednotka práce, která se provádí na existujícím vlákně. Vlákno je systémový prostředek s vlastním zásobníkem. Korutiny jsou tisíckrát lehčí než vlákna a neblokují prostředky při pozastavení.
Dispatchers.IO je určen pro blokující I/O operace (síť, soubory) a v případě potřeby může vytvářet nová vlákna. Dispatchers.Default má fond pevné velikosti (počet jader CPU) pro výpočty náročné na CPU.
Job.cancel() ruší korutinu a všechny její děti. Pro kontrolu zrušení uvnitř korutiny použijte ensureActive() — vyvolá CancellationException, pokud je korutina zrušena.
Ano — prostřednictvím knihovny kotlinx-coroutines-rx3. Poskytuje funkce awaitSingle, awaitFirst a další pro převod Observable/Single na suspend funkce a zpět pomocí flowable.
Flow — studený asynchronní datový tok, obdoba RxJava Observable pro korutiny. Flow emituje hodnoty sekvenčně a končí výjimkou nebo úspěchem. Podporuje operátory map, filter, catch a další.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také