Middle
Hoe coroutines in Kotlin-projecten te configureren en te gebruiken?
sobes.tech AI
Antwoord van AI
Om de coroutines te configureren, moet je de juiste afhankelijkheid toevoegen aan het build.gradle-bestand.
// build.gradle (app module)
dependencies {
//... andere afhankelijkheden
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") // Voor JVM, Android, JS, Native
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3") // Voor Android (als je Dispatchers.Main nodig hebt)
}
Het gebruik van coroutines omvat:
-
Scope: Het bepalen van het gebied waarin coroutines worden uitgevoerd en hun levenscyclus beheren.
GlobalScope: Het hele applicatiegebied, voorzichtig gebruiken vanwege mogelijk geheugenlek.CoroutineScope: Expliciet aangemaakt, stelt je in staat om het annuleren van coroutines te controleren.- Vooraf gedefinieerde scopes in frameworks (bijvoorbeeld
lifecycleScopein Android ViewModel).
// Voorbeeld met CoroutineScope val myScope = CoroutineScope(Dispatchers.Default + SupervisorJob()) // Scope met Dispatcher en Job fun performBackgroundTask() { myScope.launch { // Start een coroutine // Lange berekening } } fun cancelAllTasks() { myScope.cancel() // Annuleer alle coroutines in de Scope } -
Coroutine builders: Functies om coroutines te starten.
launch: Start een coroutine die geen resultaat expliciet retourneert (Job).async: Start een coroutine die een resultaat retourneert alsDeferred.
import kotlinx.coroutines.* suspend fun fetchData() = coroutineScope { // coroutineScope - builder voor gestructureerde concurrency val data1 = async { networkCall1() } // async retourneert Deferred val data2 = async { networkCall2() } // Verwerking van gegevens na ontvangst data1.await() // Resultaat ophalen van Deferred, coroutine wordt gepauzeerd tot voltooiing data2.await() } suspend fun networkCall1(): String { delay(1000) // Simulatie van netwerkverzoek return "Data 1" } suspend fun networkCall2(): String { delay(1500) return "Data 2" } fun startFetching() = runBlocking { // runBlocking - builder om huidige thread te blokkeren launch { // launch geeft Job terug println("Fetching data...") fetchData() println("Data fetched!") } } -
Dispatchers: Bepalen op welke thread of threadpool de coroutine wordt uitgevoerd.
Dispatchers.Default: Voor CPU-intensieve taken.Dispatchers.IO: Voor blokkerende I/O-operaties (bestands- en netwerktoegang).Dispatchers.Main: Hoofdthread (alleen voor Android en Swing/JavaFX).Dispatchers.Unconfined: Start de coroutine in de oproepende thread, slaapt, en wordt hervat in de thread die hervat.
import kotlinx.coroutines.* fun simpleTask() { GlobalScope.launch(Dispatchers.IO) { // Dispatcher specificatie // Voer I/O-operatie uit println("Running on thread: ${Thread.currentThread().name}") } } fun main() = runBlocking { launch(Dispatchers.Default) { println("Default thread: ${Thread.currentThread().name}") } launch(Dispatchers.Unconfined) { println("Unconfined thread 1: ${Thread.currentThread().name}") delay(100) // Slaap println("Unconfined thread 2: ${Thread.currentThread().name}") // Hervatting op andere thread (mogelijk) } delay(200) // Wacht op het voltooien van coroutines } -
Suspending functies: Functies gemarkeerd met
suspend, die kunnen worden gepauzeerd en hervat zonder het thread te blokkeren. Alleen aan te roepen vanuit andere suspending functies of binnen een coroutineblok. -
Annulering en uitzonderingen: Coroutines ondersteunen gestructureerde annulering en propagatie van uitzonderingen.
- Annulering:
import kotlinx.coroutines.* fun cancellableTask() = GlobalScope.launch { try { repeat(1000) { i -> println("Working $i ...") delay(100) // suspend functie die annulering respecteert } } catch (e: CancellationException) { println("Task was cancelled!") } finally { println("Cleaning up...") } } fun main() = runBlocking { val job = cancellableTask() delay(500) // Wacht een beetje job.cancelAndJoin() // Annuleer en wacht op voltooiing } - Uitzonderingen: Bij
launchleidt een niet-afgevangen uitzondering tot een crash van de app (standaard in Android). Bijasyncwordt de uitzondering gegooid bijawait(). Voor fijnmazige controle wordenCoroutineExceptionHandlerofSupervisorJobgebruikt.
import kotlinx.coroutines.* fun main() = runBlocking { val handler = CoroutineExceptionHandler { _, exception -> println("Caught exception: $exception") } val job = GlobalScope.launch(handler) { // Toepassing handler throw IllegalStateException("Something went wrong") } job.join() // Wachten op voltooiing } - Annulering: