Kompletní průvodce korutinami Kotlin: Zvládnutí launch, async a await

  • Základní rozdíly mezi použitím metody launch pro úlohy bez návratu a metodou async pro získání výsledků pomocí metody await.
  • Efektivní správa vláken pomocí Dispatchers.Main, IO a Default, aby se zabránilo blokování uživatelského rozhraní.
  • Implementace strukturované souběžnosti a řízení životního cyklu pomocí CoroutineScope a Job.

Kotlin Coroutines: Zvládnutí launch, async a await

Pokud jste někdy měli pocit, že se vaše aplikace pro Android zamrzla nebo přestala reagovat při stahování něčeho, pravděpodobně máte problém s hlavním tématem. Ve světě mobilního vývoje je udržení plynulého chodu aplikace při plnění náročných úkolů svatým grálem a právě zde přicházejí na řadu korutiny Kotlin . V podstatě nám umožňují psát asynchronní kód, aniž bychom se museli zabývat nekonečnými zpětnými voláními.

Představte si korutiny jako lehká vlákna ; nevytvářejí pokaždé nové vlákno operačního systému, ale místo toho využívají skupiny existujících vláken a velmi chytrý systém plánování. Díky tomu jsou neuvěřitelně efektivní a kód se čte téměř sekvenčně, i když v zákulisí probíhá celá řada pauz a obnovení, takže si uživatel na obrazovce nevšimne žádného zpoždění.

Tajemství pozastavení: pozastavení a obnovení

Na rozdíl od běžných funkcí, korutiny zavádějí dva klíčové koncepty. Zaprvé, existuje `suspend` , která umožňuje pozastavit provádění úlohy a zároveň uložit její aktuální stav. Zadruhé, existuje `resume` , která obnoví provádění přesně tam, kde skončilo. Zajímavé je, že pozastavená funkce neblokuje vlákno, ve kterém běží; jednoduše se oddálí, aby umožnila dalším úlohám pokračovat, zatímco čeká na odpověď, například z databáze.

Je důležité si uvědomit, že použití klíčového slova `suspend` automaticky nepřesune kód do sekundárního vlákna. Abychom dosáhli bezpečnosti hlavního vlákna , musíme tyto funkce kombinovat s vhodnými dispečery a zajistit, aby operace náročné na zdroje nezahlcovaly uživatelské rozhraní.

Kotlin Coroutines: Zvládnutí launch, async a await
Související článek:
Kompletní průvodce Kotlinem pro Android vývojáře: Koncepty a základy

Dispečeri: Kde se děje ta magie?

Abychom Kotlinu sdělili, které vlákno má použít ke spuštění každého kusu kódu, používáme Dispatchery . Ne všechny Dispatchery slouží stejnému účelu, takže je třeba vědět, jak vybrat ten správný.

  • Dispečeri.HlavníTento nástroj je zodpovědný za interakci s uživatelským rozhraním. Měl by být používán pouze pro rychlé vizuální změny nebo interakci s LiveData, protože cokoli složitého v tomto nástroji povede k chybě. Aplikace nereaguje (ANR).
  • Dispečeri.IOJe optimalizován pro vstupně/výstupní úlohy. Je to ideální místo pro Volání API, číst soubory z disku nebo spravovat databázi místnosti.
  • Dispečeri.VýchozíNavrženo pro práci náročnou na CPU, například když potřebujete zpracovat obří JSON nebo seřadit obrovský seznam položek.

Velmi běžnou a doporučovanou technikou je použití funkce `withContext` . Tato funkce nám umožňuje změnit dispečera v rámci pozastavené funkce bez nutnosti zpětných volání. Tímto způsobem se vývojář volající funkci nemusí starat o to, ve kterém vlákně se nachází, protože samotná funkce zajišťuje svou vlastní bezpečnost interním přepnutím na IO nebo výchozí vlákno.

Spuštění vs. asynchronní: Který si vybrat?

Když chceme spustit korutinu, máme dvě hlavní cesty v závislosti na tom, zda potřebujeme, aby úloha něco vrátila, nebo ne.

Operátor `launch` je to, čemu říkáme „spuštění a zapomnění“. Používá se pro úlohy, které nevrací výsledek, jako je aktualizace barvy na obrazovce nebo ukládání dat do mezipaměti. Vrací objekt `Job` , což je v podstatě dálkové ovládání, které nám umožňuje zrušit korutinu, pokud ji již nepotřebujeme.

Na druhou stranu, `async` se používá, když potřebujeme návratovou hodnotu. Tento operátor vrací `Deferred<T>` , což je jako slib, že v budoucnu bude výsledek. Abychom tuto hodnotu získali, musíme zavolat funkci `await()` , která pozastaví provádění, dokud nebude výsledek připraven. Silnou stránkou `async` je, že umožňuje paralelní volání ; pokud provedeme tři `async` požadavky, všechny tři půjdou na server současně, což optimalizuje celkovou dobu čekání.

Strukturovaná souběžnost a správa životního cyklu

Aby se zabránilo dalšímu běhu korutin po zavření obrazovky uživatelem (což by způsobilo úniky paměti), Kotlin používá strukturovanou souběžnost . To vše je spravováno prostřednictvím CoroutineScope , který sleduje všechny korutiny spuštěné v něm.

V Androidu se nejběžněji používají předdefinované obory platnosti, jako například `viewModelScope` nebo `lifecycleScope` . Ty jsou skvělé, protože automaticky zruší veškerou čekající práci, když je `ViewModel` zničen nebo `Activity` ukončena. Pokud potřebujete vytvořit vlastní obor platnosti, můžete zkombinovat `Job` a `Dispatcher`, ale vždy nezapomeňte v metodě cleanup vaší třídy zavolat ` scope.cancel()` .

Zpracování chyb a speciálních případů

Zpracování výjimek se liší v závislosti na použitém konstruktoru. V `launch` se pokud dojde k chybě a není zachycena, aplikace okamžitě zavře. V `async` je však výjimka uložena v objektu `Deferred` a nebude vyvolána, dokud nebude volána ` await()` , což může někdy způsobit, že chyby zůstanou bez povšimnutí, pokud si nejste opatrní.

Aby se to dalo zvládnout přirozeně, je nejlepší zabalit volání do bloků try-catch , díky čemuž se asynchronní kód jeví stejně přímočarý jako synchronní. Navíc, pokud chceme, aby byla korutina imunní vůči zrušení ze strany svého rodiče, můžeme použít `NonCancellable` s `withContext`, i když by to mělo být provedeno velmi opatrně, aby se zabránilo narušení hierarchie souběžnosti.

Integrace všech těchto funkcí s knihovnami, jako je Retrofit , je hračka, protože moderní verze nativně podporují pozastavené funkce. Ideální pracovní postup je v konečném důsledku takový, aby ViewModel spouštěl korutinu, Repository zpracovával obchodní logiku a Data Source odesílal požadavky na Dispatchers.IO , přičemž se vždy zachovává plynulé rozhraní a čistý kód.

Jak čistě migrovat vrstvu podnikové Android aplikace do Kotlin Multiplatform
Související článek:
Jak čistě migrovat vrstvu podnikové Android aplikace do Kotlin Multiplatform

Používání korutin transformuje vývoj pro Android a nahrazuje složitost tradičních vláken efektivním systémem pozastavení a rozsahy vázanými na životní cyklus. Pochopením rozdílu mezi rychlým spouštěním příkazu `launch` a paralelní silou příkazu `async` s `await`, spolu se správnou volbou dispečerů, můžete vytvořit robustní software, který maximalizuje zdroje zařízení, aniž by to ohrozilo uživatelský komfort. Sdílejte tuto příručku, aby se o ní mohli dozvědět i ostatní uživatelé.


Obchod Google Play bez účtu Google
Může vás zajímat:
Jak stahovat aplikace z Obchodu Play bez účtu Google
Přidat jako preferovaný zdroj v Googlu