Az AsyncTask lecserélése Kotlin korutinjaira

Még mindig használja az AsyncTask-ot Android-alkalmazásaiban? Valószínűleg már nem kellene. Így cserélheti ki őket Kotlin korutinjaira.

Az Androidon nagyon sokáig, ha bármit aszinkron módon kellett volna csinálnia egy alkalmazás elkészítésekor, valószínűleg az AsyncTask-ot használta. Az AsyncTask egy API az Android keretrendszerében, amely megkönnyíti (ish) a műveletek futtatását a háttérben, és az értékek visszaadását, ha végzett. És ennek van értelme. A Kotlin's Coroutinestól ​​eltérően az AsyncTask már egy ideje létezik, és közvetlenül be van építve.

Az AsyncTask tervezési filozófiája és megvalósítása azonban az évek során kissé elavulttá vált. Emiatt a Google-nak van elavult az AsyncTask API. Ha akarja, továbbra is használhatja, de a Google nem javasolja. Szerencsére az AsyncTask alternatíváinak egész sora létezik, beleértve a Kotlin nyelv egyik jellemzőjét – a korutinokat.

A Kotlin coroutines API egy hihetetlenül hatékony keretrendszer, amely lehetővé teszi egy csomó dolog elvégzését. Ez a cikk csak a felszínét fogja megkarcolni annak, ami lehetséges. Áttekintjük az AsyncTask-ról a korutinokra való átálláshoz szükséges alapokat.

Korutintámogatás hozzáadása

Mielőtt elkezdené használni a korutinokat, ténylegesen hozzá kell adnia őket a projekthez.

Kotlin támogatás hozzáadása

Ha már telepítette a Kotlint, ugorjon a következő szakaszra. Ellenkező esetben hozzá kell adnia a Kotlin támogatást a projekthez. További részletekért tekintse meg az oktatóanyagomat a Kotlin hozzáadása egy meglévő projekthez.

Coroutine Libraries hozzáadása

A modulszinten build.gradle, tartalmazza a következő függőségeket.

dependencies {
...
implementation 'org.jetbrains.kotlinx: kotlinx-coroutines-core: 1.5.0'
implementation 'org.jetbrains.kotlinx: kotlinx-coroutines-android: 1.5.0'
}

Szinkronizálja projektjét, és Kotlin korutinjai mostantól használhatók lesznek.

Korutinok használata

A CoroutineScope megvalósítása

A korutinok használatához rendelkezésre kell állnia egy CoroutineScope példánynak. Ennek egy egyszerű módja, ha csak implementálja a tartalmazó osztályba.

Például egy CoroutineScope megvalósításához egy tevékenységben:

classSomeActivity : AppCompatActivity, CoroutineScope by MainScope() {
...

override fun onDestroy(){
super.onDestroy()

cancel()
}
}

Ezzel a SomeActivity megvalósítja a CoroutineScope felületet a MainScope osztályon keresztül. A MainScope kezeli a CoroutineScope összes megvalósítási logikáját, miközben lehetővé teszi a CoroutineScope metódusok használatát. Hívás cancel() ban ben onDestroy() gondoskodik arról, hogy a tevékenység kilépése után ne fusson tovább aszinkron logika.

Az AsyncTask lecserélése korutinokra

Tegyük fel, hogy egy tevékenységen belül van egy AsyncTask, amely egy hosszan tartó műveletet hajt végre a háttérben, és végül egy karakterláncot ad vissza. Valami a következőhöz hasonló.

private inner classSomeTask : AsyncTask() {
override fun doInBackground(vararg params: Void): String {
try {
//Pretend this is an actual operation that takes 10 seconds and not just sleeping.
Thread.sleep(10000);
} catch (e: InterruptedException) {}

return"SomeString";
}

override fun onPostExecute(result: String) {
val someTextView = findViewById(R.id.some_text_view)
someTextView.text = result
}
}

Ezt könnyű korutinnal helyettesíteni. Csak használja a async() módszer. Kotliné async() azon a szálon fut, amelyen elindították, de aszinkron módon. Ez azt jelenti, hogy frissítheti a Nézeteket és hasonlókat anélkül, hogy aggódnia kellene a megfelelő szál használata miatt.

classSomeActivity : AppCompatActivity(), CoroutineScope by MainScope() {
...

private fun doOperation(){
async {
//Inside coroutine scopes (like inside async here), delay is used instead of Thread.sleep.
delay(10000)

val someTextView = findViewById(R.id.some_text_view)
someTextView.text = "SomeString"
}
}
}

Amint látja, a korutinok használata sokkal egyszerűbb lehet, mint az AsyncTask használata. Nem kell csak hívni async() és hadd tegye a dolgát. Tarthat egy hivatkozást, és meg is várhatja, hogy befejezze.

val asyncJob = async {
//Some operation
}
//Pause here until the async block is finished.
asyncJob.await()

//This won't run until asyncJob finishes, but other operations started before the job, or started from another method, can still run.
doSomethingElse()

Értékek visszaadása aszinkronnal

Akár egy értéket is visszaadhat innen async() ha akarod. Tehát az eredeti példa valami ilyesmivé válhat.

classSomeActivity : AppCompatActivity(), CoroutineScope by MainScope() {
...
private fun doOperation(){
val asyncJob = async {
//Inside coroutine scopes (like inside async here), delay is used instead of Thread.sleep.
delay(10000)

//Whatever the type is of the last line is what async() eventually returns.
"SomeString"
}

val result = asyncJob.await()

val someTextView = findViewById(R.id.some_text_view)
someTextView.text = result
}
}

A withContext használata

A kényelem kedvéért Kotlin gondoskodik withContext(). Ez beépíti az egészet await() dolog, és csak visszaadja az értéket.

classSomeActivity : AppCompatActivity(), CoroutineScope by MainScope() {
...
private fun doOperation(){
//Run asynchronously on the main Thread.
val result = withContext(Dispatchers.Main) {
delay(10000)

"SomeResult"
}

val someTextView = findViewById(R.id.some_text_view)
someTextView.text = result
}
}

Következtetés

A fenti példák csak néhány alapvető használatot mutatnak be a Kotlin-korutinokkal az induláshoz. Nem kell korlátoznia a korutinokat a tevékenységekre vagy akár bármire, amely megfelelő életciklussal rendelkezik. Alapvetően bárhol futtathatja őket. Vannak fejlettebb műveletek is, például annak kiválasztása, hogy melyik szál futtassa az aszinkron logikát. Ez az útmutató elsősorban annak bemutatására szolgál, hogyan cserélhető le egy egyszerű AsyncTask egy egyszerű korutinnal.

A korutin működésével és a fejlettebb funkcióik kihasználásával kapcsolatos további részletekért tekintse meg a hivatalos Kotlin-dokumentáció.