Cum să înlocuiți AsyncTask cu Coroutines lui Kotlin

Încă folosiți AsyncTask în aplicațiile Android? Probabil că nu ar trebui să mai fii. Iată cum să le înlocuiți cu Coroutinele lui Kotlin.

De foarte mult timp în Android, dacă ai trebuit să faci ceva asincron atunci când faci o aplicație, probabil că ai fi folosit AsyncTask. AsyncTask este un API din cadrul Android care facilitează (ish) rularea operațiunilor în fundal și returnarea valorilor când ați terminat. Și asta are sens. Spre deosebire de Coroutines de la Kotlin, AsyncTask există de ceva vreme și este încorporat direct.

Cu toate acestea, atât filosofia de proiectare, cât și implementarea AsyncTask au devenit oarecum depășite de-a lungul anilor. Din această cauză, Google are a depreciat API-ul AsyncTask. Îl puteți folosi în continuare dacă doriți, dar Google nu vă recomandă să faceți acest lucru. Din fericire, există o mulțime de alternative la AsyncTask, inclusiv o caracteristică a limbajului Kotlin - coroutine.

API-ul coroutines de la Kotlin este un cadru incredibil de puternic care vă permite să faceți o mulțime de lucruri. Acest articol nu va face decât să zgârie suprafața a ceea ce este posibil. Vom trece peste elementele de bază necesare pentru a migra de la AsyncTask la coroutines.

Adăugarea suportului Coroutines

Înainte de a putea începe să utilizați coroutine, trebuie să le adăugați efectiv la proiectul dvs.

Adăugarea suportului Kotlin

Dacă aveți deja implementat Kotlin, treceți la următoarea secțiune. În caz contrar, va trebui să adăugați suport Kotlin la proiectul dvs. Consultați tutorialul meu despre adăugarea lui Kotlin la un proiect existent pentru mai multe detalii.

Adăugarea de biblioteci Coroutine

La nivelul dvs. de modul build.gradle, include următoarele dependențe.

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

Sincronizați-vă proiectul, iar corutinele lui Kotlin vor fi acum disponibile pentru utilizare.

Folosind Coroutines

Implementarea unui CoroutineScope

Pentru a utiliza coroutine, va trebui să aveți o instanță CoroutineScope disponibilă. O modalitate ușoară de a face acest lucru este să o implementați în clasa dvs.

De exemplu, pentru a implementa un CoroutineScope într-o activitate:

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

override fun onDestroy(){
super.onDestroy()

cancel()
}
}

Acest lucru va face SomeActivity să implementeze interfața CoroutineScope prin intermediul clasei MainScope. MainScope va gestiona toată logica de implementare pentru CoroutineScope, permițându-vă în același timp să utilizați metodele CoroutineScope. Apel cancel() în onDestroy() se asigură că nicio logică asincronă nu continuă să ruleze după ieșirea activității.

Înlocuirea AsyncTask cu Coroutines

Să presupunem că aveți un AsyncTask în interiorul unei activități care efectuează o operație de lungă durată în fundal și în cele din urmă returnează un șir. Ceva de genul următor.

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
}
}

Înlocuirea acesteia cu o corutine este ușoară. Folosește doar async() metodă. a lui Kotlin async() rulează pe orice Thread pe care a fost lansat, dar o face asincron. Aceasta înseamnă că puteți actualiza Views și altele fără să vă faceți griji cu privire la utilizarea Thread-ului potrivit.

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"
}
}
}

După cum puteți vedea, utilizarea coroutinelor poate fi mult mai simplă decât utilizarea AsyncTask. Nu trebuie doar să suni async() și lasă-l să-și facă treaba, totuși. Puteți păstra o referință la el și chiar așteptați să se termine.

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()

Valori returnate cu asincron

Puteți chiar returna o valoare de la async() dacă doriți. Deci exemplul original ar putea deveni ceva de genul acesta.

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
}
}

Folosind withContext

Pentru comoditate, Kotlin oferă withContext(). Aceasta aliniază întregul await() lucru și doar îți returnează valoarea.

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
}
}

Concluzie

Exemplele de mai sus sunt doar câteva utilizări de bază ale coroutinelor lui Kotlin pentru a începe. Nu trebuie să limitați corutinele la Activități sau chiar orice cu un ciclu de viață adecvat. Le puteți rula practic oriunde. Există, de asemenea, operațiuni mai avansate, cum ar fi alegerea care Thread ar trebui să ruleze logica asincronă. Acest ghid este în principal pentru a arăta cum să înlocuiți un simplu AsyncTask cu o simplă corutine.

Pentru mai multe detalii despre cum funcționează corutinele și despre cum puteți folosi funcțiile lor mai avansate, consultați documentația oficială Kotlin.