Coroutine Builder — funktioner i Kotlin Coroutines som skapar och startar korutiner och bestämmer deras körningssätt. Byggarna launch, async, runBlocking och produce täcker olika scenarier: från bakgrundsuppgifter till parallella beräkningar med resultatåtergivning. Enligt JetBrains, 2024 är Coroutine Builder grunden för korutinmodellen och tillhandahåller strukturerad samtidighet och livscykelhantering.
Huvudpunkter
Coroutine Builder — är en tilläggsfunktion i Kotlin som tar emot CoroutineScope och ett suspend-block, skapar och startar en ny korutin. Varje byggare bestämmer hur korutinen ska köras: med eller utan resultat, med blockering av tråden eller asynkront. Byggare är ingångspunkter till språkets korutinmodell.
Alla byggare arbetar genom CoroutineScope, som hanterar livscykeln för underordnade korutiner. När scopet annulleras annulleras alla korutiner som startats genom det automatiskt — detta är principen för strukturerad samtidighet. Detta tillvägagångssätt förhindrar korutinläckor och garanterar förutsägbar slutföring.
import kotlinx.coroutines.*
fun main() = runBlocking {
// Byggare körs inom CoroutineScope
val job = launch {
delay(1000L)
println("Världen!")
}
println("Hej,")
job.join()
}
Kotlin tillhandahåller fyra inbyggda korutinbyggare: launch, async, runBlocking och produce. Var och en har sin egen returtyp och tillämpningsområde. För mobilutveckling på Android är de viktigaste launch och async — de fungerar icke-blockerande och integreras med arkitekturkomponenter.
| Byggare | Returtyp | Trådblockering | Scenario |
|---|---|---|---|
| launch | Job | Nej | Fire-and-forget-uppgifter |
| async | Deferred<T> | Nej | Parallella beräkningar |
| runBlocking | T | Ja | Tester, main-funktion |
| produce | ReceiveChannel<E> | Nej | Strömmande överföring (deprecated) |
Varje byggare accepterar ytterligare parametrar: CoroutineStart (startstrategi), CoroutineContext (dispatcher, undantag) och ett namngivet kodblock. Som standard startas korutinen omedelbart (CoroutineStart.DEFAULT).
launch — den mest använda byggaren inom Android-utveckling. Den startar en korutin som inte returnerar något resultat och returnerar ett Job-objekt för att hantera dess livscykel. Detta är det ideala valet för operationer där endast en bieffekt behövs: spara i databas, skicka analysdata, uppdatera UI.
Byggaren launch accepterar CoroutineScope, valfri CoroutineContext och ett suspend-block. Det returnerade Job gör det möjligt att annullera korutinen, vänta på dess slutförande eller kontrollera status.
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
val job: Job = scope.launch(CoroutineStart.LAZY) {
val data = fetchFromNetwork()
saveToDatabase(data)
}
job.start()
job.join()
Parametern CoroutineStart.LAZY fördröjer starten tills ett explicit anrop av start() eller join(). Detta är användbart för fördröjd initiering och villkorlig start. För standard omedelbar start används CoroutineStart.DEFAULT eller parametern utelämnas.
async — byggare som returnerar Deferred<T> — ett asynkront löfte om resultat. Anropet await() pausar korutinen tills resultatet erhålls, utan att blockera tråden. Detta är den grundläggande mekanismen för parallella uppgifter i Kotlin-korutiner.
async är särskilt effektivt när flera oberoende operationer måste utföras samtidigt. Till skillnad från sekventiell anrop av suspend-funktioner startar async korutiner parallellt, vilket förkortar den totala körtiden.
suspend fun fetchUserData(): UserData {
val deferred1 = CoroutineScope(Dispatchers.IO).async { api.getProfile() }
val deferred2 = CoroutineScope(Dispatchers.IO).async { api.getSettings() }
val deferred3 = CoroutineScope(Dispatchers.IO).async { api.getNotifications() }
return UserData(
profile = deferred1.await(),
settings = deferred2.await(),
notifications = deferred3.await()
)
}
Deferred ärver från Job, så async stöder alla livscykeloperationer: annullering, väntan på slutförande, hantering av undantag. När scopet annulleras annulleras underordnade Deferred-korutiner automatiskt.
runBlocking — den enda byggaren som blockerar den aktuella tråden tills korutinen är slutförd. Den skapar en ny CoroutineScope och startar den angivna korutinen, vilket blockerar den anropande tråden. Används i ingångspunkter main(), i tester och vid integrering med blocking-kod.
runBlocking är motiverat i tre scenarier: applikationens ingångspunkt (main), enhetstester av suspend-funktioner och integrering med callback-baserade bibliotek där suspend inte kan användas. I produktionskod för Android rekommenderas användning av runBlocking på huvudtråden absolut inte.
class CoroutineTest {
@Test
fun `test suspend function`() = runBlocking {
val result = mySuspendFunction()
assertEquals("expected", result)
}
}
För tester rekommenderas att använda kotlinx-coroutines-test med TestCoroutineDispatcher istället för runBlocking — detta ger tidskontroll och undviker blockeringar i testmiljön.
Valet av Coroutine Builder beror på det returnerade resultatet och körningsscenariot. Om operationen inte kräver dataåtergivning — använd launch. Om resultatet av en asynkron operation behövs — async. runBlocking tillämpas endast för bridging och produce ersätt med Flow för reaktiva strömmar.
I Android-projekt som använder Kotlin Coroutines är det huvudsakliga paret av byggare launch och async. launch används i ViewModel och UseCases för att starta korutiner och async — för parallella förfrågningar till nätverk eller databas. Moderna bibliotek (Ktor, Room) stöder redan suspend-funktioner, vilket minimerar behovet av direkt användning av async.
Vanliga frågor
launch returnerar Job och returnerar inte körningsresultat, medan async returnerar Deferred<T> — ett objekt från vilket resultatet kan erhållas via await(). launch används för fire-and-forget-operationer, async — för uppgifter som returnerar data.
Rekommenderas inte. runBlocking på huvudtråden orsakar ANR och blockerar UI. Använd lifecycleScope.launch inuti Activity och Fragment — detta är en inbyggd lösning utan blockeringar.
Byggaren launch returnerar ett Job-objekt som gör att du kan kontrollera korutinens livscykel: annullera (cancel), vänta på slutförande (join), kontrollera status (isActive, isCompleted, isCancelled).
Deferred<T> — är ett asynkront löfte om resultat som returneras av byggaren async. Det ärver från Job och lägger till metoder await() för att erhålla resultat, getCompleted() för icke-blockerande åtkomst och getCompletionExceptionOrNull() för att kontrollera undantag.
Använd parametern CoroutineStart.LAZY: scope.launch(start = CoroutineStart.LAZY) { ... }. Anropa sedan job.start() eller job.join() för faktisk start. Detta är användbart för fördröjd initiering och villkorlig körning av korutiner.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också