Úvod do Kotlin Coroutines
Technology
7
 min read
April 15, 2021

Úvod do Kotlin Coroutines

Tomáš Paronai
Tomáš Paronai
Android Developer

Coroutiny sa stávajú bežnou technologiou pri vývoji mobilných aplikácií. Mnohí z nás už tento koncept poznajú alebo sa s ním stretli. Avšak stále nám chýba fundementálne pochopenie.

Routine vs Coroutine

Každému developerovi by malo byť jasné, čo znamená slovíčko routine. Routine je základná stavebná jednotka každého programu. Je to súbor inštrukcií, ktoré vykonávajú úlohy, tiež známy pod pojmami ako funkcia alebo metóda. Príkazy sa vykonávajú sekvenčne zhora nadol. V praxi to voláme synchrónne programovanie.

V tomto konkrétnom príklade môžeme vidieť, ako z neho prebieha nasledovný výstup. Funkcia routine predstavuje prácu, ktorú program vykonáva a trvá delay ms dlho. Druhá routine čaká 500ms na prvú, kým skončí. Routine 1 blokuje vlákno, kým neskončí. Takáto inštrukcia je známa pod pojmom blocking.

Príklad zobrazený pomocou diagramu:

coroutines diagram

V praxi nesenkvenčné programovania voláme asynchrónne. V tomto prípade sa inštrukcie jedného programu vykonávajú súbežne. Asynchrónne programovanie je zvlášť dôležité v Androide. Predstavme si situáciu, kedy používateľ v aplikácií čaká, kým sa stiahnu obrázky. Ak by sa sťahovali obrázky na rovnakom vlákne, na ktorom beží celé užívateľské rozhranie, celé rozhranie by stálo a čakalo, kým sa inštrukcie na stiahnutie a uloženie obrázkov dokončia. Aplikácia by sa javila ako pokazená a viedlo by to k veľmi nepríjemnému užívateľskému zážitku.

Najčastejším riešením by bolo použiť nové vlákno - Thread alebo RxJava. Všetky tieto spôsoby majú svoje výhody aj nevýhody. Skúsme si ukázať predchádzajúci príklad asynchrónne.

Thread

RxJava

V oboch prípadoch dosiahneme nasledujúci výstup:

Ako je z výstupu jasné, oba príkazy sa spustili jeden za druhým, teda nečakali na seba, ale bežali súbežne. Druhá routina je rýchlejšia, čiže skončila skôr. Takéto inštrukcie nazývame nonblocking.

multithread visualization via diagram

Pri vláknach nemáme kontrolu nad novými vláknami. Ak si predstavíme, že main je bežiaca Android aplikácia a my ju vypneme po zavolaní routine, tak nám vzniká memory leak.

Pri RxJave tento problém nemáme, lebo disponujeme naše inštrukcie po skončení programu, ale pri samotnom frameworku je potrebné si pamätať veľké množstvo inštrukcií, ktoré s multithredingom pracujú. Ak by sme v main funkcii nezavolali Thread.sleep(600), výpis "main ends" by sa vypísal predtým, ako by skončili naše routine funkcie a to z dôvodu, že naše routine funkcie bežia na inom vlákne ako main.

Coroutine

Z názvu coroutine si vieme už predstaviť, že nejde o bežný súbor inštrukcií, ktoré sa vykonávajú sekvenčne.

Na prvý pohľad sa môže zdať, že na predchádzajúcom obrázku je niekoľko nových neznámych príkazov. Príkaz runBlocking blokuje vlákno, na ktorom príkaz beží a spustí novú coroutinu. runBlocking voláme preto, lebo sa program sa vykonáva zhora nadol, ak chceme niekde vsunúť coroutinu a zároveň chceme, aby program nepokračoval, kým coroutina neskončí. Je to jeden z konštruktorov pre coroutiny.

Ďalším konštruktom coroutiny je launch, ktorý ju aj spúšťa. O všetkých konštruktoroch a rozdieloch medzi nimi vám poviem v ďalšom článku. Tieto coroutiny vkladáme do joinAll, od ktorej exekúcia príkazov nepokračuje, kým sa nevyhodnotia všetky coroutiny. Funkcia coroutine ****je vskutku to isté ako routine z predchádzajúceho príkladu. Nazvali sme to konvenčne. Ak spustíme tento príklad, dostaneme nasledujúci výsledok.

Jeden z najväčších rozdielov medzi multithreadingom a kotlin coroutinami je, že coroutiny bežia na rovnakom vlákne, na ktorom boli vytvorené. Pre pravdivosť tohto výroku, skúste si vypísať názov vlákna vo funkcií *routine* a *coroutine - Thread.currentThread().name.*

Aký je teda princíp? Vytvorenie a manažovanie ďalšieho vlákna je náročné na pamäť aj CPU. Takto vyzerá práca coroutiny na diagrame.

Uľahčuje sa nám najmä čitateľnosť kódu, lebo nie je potrebné vkladať callbacky ak by sme mali návratovú hodnotu. V ďalšom článku si ukážeme jednoduché použitie všetkých troch spôsobov asynchrónneho programovania pri komunikácií so serverom alebo s databázou.

Zaujíma vás Android? Navštívte článok o Constraint Layout Helpers

Like what you see?
Join our newsletter.

Great! Welcome to newsletter.
Oops! Something went wrong while submitting your email.
High quality content once a month. No spam, we promise.
Your personal data is processed in accordance with our Memorandum on Personal Data Protection.

Páči sa vám náš content?
Odoberajte newsletter.

Great! Welcome to newsletter.
Oops! Something went wrong while submitting your email.
Vaše osobné údaje sú spracované v súlade s našim Memorandom na ochranu osobných údajov.