Hoe AsyncTask te vervangen door Kotlin's Coroutines

Gebruikt u nog steeds AsyncTask in uw Android-apps? Dat zou je waarschijnlijk niet meer moeten zijn. Hier leest u hoe u ze kunt vervangen door Kotlin's Coroutines.

Als je in Android heel lang iets asynchroon moest doen bij het maken van een app, gebruikte je waarschijnlijk AsyncTask. AsyncTask is een API in het Android-framework die het gemakkelijk maakt om bewerkingen op de achtergrond uit te voeren en waarden terug te geven als ze klaar zijn. En dat is logisch. In tegenstelling tot Kotlin's Coroutines bestaat AsyncTask al een tijdje en is het meteen ingebouwd.

Zowel de ontwerpfilosofie als de implementatie van AsyncTask zijn in de loop der jaren echter enigszins verouderd. Daarom heeft Google dat gedaan heeft de AsyncTask API beëindigd. Je kunt het nog steeds gebruiken als je wilt, maar Google raadt dit niet aan. Gelukkig zijn er een hele reeks alternatieven voor AsyncTask, waaronder een functie van de Kotlin-taal: coroutines.

De coroutines API van Kotlin is een ongelooflijk krachtig raamwerk waarmee je een heleboel dingen kunt doen. Dit artikel zal alleen maar de oppervlakte schetsen van wat mogelijk is. We bespreken de basisprincipes die nodig zijn om van AsyncTask naar coroutines te migreren.

Coroutines-ondersteuning toevoegen

Voordat u coroutines kunt gaan gebruiken, moet u ze daadwerkelijk aan uw project toevoegen.

Kotlin-ondersteuning toevoegen

Als je Kotlin al hebt geïmplementeerd, ga dan verder met de volgende sectie. Anders moet u Kotlin-ondersteuning aan uw project toevoegen. Bekijk mijn tutorial over het toevoegen van Kotlin aan een bestaand project voor meer details.

Coroutine-bibliotheken toevoegen

Op jouw moduleniveau build.gradle, omvatten de volgende afhankelijkheden.

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

Synchroniseer uw project en de coroutines van Kotlin zijn nu beschikbaar voor gebruik.

Coroutines gebruiken

Implementatie van een CoroutineScope

Om coroutines te kunnen gebruiken, moet u over een CoroutineScope-instantie beschikken. Een eenvoudige manier om dit te doen, is door het gewoon in uw bevattende klasse te implementeren.

Om bijvoorbeeld een CoroutineScope in een activiteit te implementeren:

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

override fun onDestroy(){
super.onDestroy()

cancel()
}
}

Hierdoor zal SomeActivity de CoroutineScope-interface implementeren via de MainScope-klasse. MainScope verzorgt alle implementatielogica voor CoroutineScope, terwijl u de CoroutineScope-methoden kunt gebruiken. Roeping cancel() in onDestroy() zorgt ervoor dat er geen asynchrone logica blijft draaien nadat de activiteit is afgesloten.

AsyncTask vervangen door Coroutines

Stel dat u een AsyncTask binnen een activiteit hebt die een langlopende bewerking op de achtergrond uitvoert en uiteindelijk een String retourneert. Iets als het volgende.

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

Dit vervangen door een coroutine is eenvoudig. Gebruik gewoon de async() methode. van Kotlin async() draait op de Thread waarop het is gelanceerd, maar doet het asynchroon. Dit betekent dat u weergaven en dergelijke kunt bijwerken zonder dat u zich zorgen hoeft te maken over het gebruik van de juiste thread.

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

Zoals u kunt zien, kan het gebruik van coroutines een stuk eenvoudiger zijn dan het gebruik van AsyncTask. Je hoeft niet zomaar te bellen async() en laat het maar zijn ding doen. Je kunt er een verwijzing naar bewaren en zelfs wachten tot het klaar is.

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

Waarden retourneren met asynchroon

U kunt zelfs een waarde retourneren async() als je wil. Het originele voorbeeld zou dus ongeveer zo kunnen worden.

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

Gebruiken metContext

Voor het gemak biedt Kotlin withContext(). Dit lijnt het geheel uit await() ding en geeft de waarde gewoon aan u terug.

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

Conclusie

De bovenstaande voorbeelden zijn slechts enkele basisgebruiken van Kotlin's coroutines om u op weg te helpen. U hoeft coroutines niet te beperken tot activiteiten of zelfs iets met een goede levenscyclus. Je kunt ze in principe overal gebruiken. Er zijn ook meer geavanceerde bewerkingen, zoals het kiezen van welke Thread de asynchrone logica moet uitvoeren. Deze handleiding is voornamelijk bedoeld om te laten zien hoe u een eenvoudige AsyncTask kunt vervangen door een eenvoudige coroutine.

Voor meer details over hoe coroutines werken en hoe u gebruik kunt maken van hun meer geavanceerde functies, bekijk de officiële Kotlin-documentatie.