launch — Coroutine Builder i Kotlin som startar en korutin utan att returnera ett resultat och returnerar ett Job-objekt för att hantera exekveringen. Denna builder implementerar fire-and-forget-mönstret: korutinen börjar arbeta i en bakgrundstråd och avslutas automatiskt. Enligt JetBrains dokumentation, 2024, är launch det huvudsakliga sättet att starta parallella uppgifter i Kotlin Coroutines.
Huvudpunkter
launch — är en Kotlin-tilläggsfunktion, tillgänglig via import kotlinx.coroutines, som skapar en ny korutin i en angiven CoroutineScope. Till skillnad från vanliga funktioner körs koden inuti launch samtidigt — korutinen kan pausas (suspend) utan att blockera tråden och återupptas senare.
Launch-buildern är en grundläggande byggsten i Kotlins korutinmodell. Den returnerar inte ett beräknat värde, men returnerar ett Job-objekt som gör det möjligt att kontrollera korutinens exekvering. Alla underordnade korutiner som startas via launch inuti en annan korutin är bundna till föräldern.
Launch-buildern definieras som en inline-funktion med flera parametrar: CoroutineScope, CoroutineContext, CoroutineStart och suspend-block. Parametrarna har standardvärden, vilket gör launch bekvämt för typiska scenarier.
public fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job
Parametern context accepterar en CoroutineContext som kombinerar dispatchern, undantagshanteraren och ett namngivet element. Oftast skickas Dispatchers.IO, Dispatchers.Main eller SupervisorJob för felisolering.
Job — det returnerade objektet som representerar korutinens livscykel. Job kan vara i tillstånden: New, Active, Completing, Completed, Cancelling, Cancelled. Varje tillstånd återspeglar exekveringsstatusen och möjliggör reaktion på förändringar.
val job = CoroutineScope(Dispatchers.IO).launch {
repeat(10) { i ->
delay(1000L)
println("Framsteg: $i")
}
}
println("Job är aktivt: ${job.isActive}")
delay(2500L)
job.cancel()
println("Job är annullerat: ${job.isCancelled}")
Job stöder hierarki: om föräldrakorutinen annulleras, annulleras alla underordnade korutiner automatiskt. SupervisorJob ändrar detta beteende — underordnade korutiner annulleras inte vid fel i en av dem.
Strukturerad samtidighet innebär att varje korutin startas i en specifik CoroutineScope, och scopet avslutas inte förrän alla underordnade korutiner har slutfört sitt arbete. launch stöder denna princip fullt ut — korutiner som startas inuti en annan korutin är dess barn.
Vid nästlad start av launch bildas ett träd av korutiner. Föräldrakorutinen väntar på att alla barn ska slutföras, vilket garanterar en förutsägbar exekveringsordning och förenklar resurshanteringen.
fun main() = runBlocking {
launch {
launch {
delay(1000L)
println("Barn 1 slutfört")
}
launch {
delay(500L)
println("Barn 2 slutfört")
}
println("Alla barn slutförda före denna rad")
}
}
Detta beteende skiljer sig från trådbaserad samtidighet, där underordnade trådar inte är bundna till föräldern. I korutiner slutförs inte föräldern förrän alla barn har slutfört sitt arbete.
Undantagshantering i launch beror på typen av Job. För ett vanligt Job sprids undantag till föräldrakorutinen och annullerar den. För SupervisorJob eller SupervisorScope isoleras undantag — felet i en underordnad korutin påverkar inte de andra.
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
scope.launch {
try {
riskyOperation()
} catch (e: Exception) {
println("Fångat: ${e.message}")
}
}
scope.launch {
println("Detta körs fortfarande tack vare SupervisorJob")
}
För global hantering av ouppfångade undantag används CoroutineExceptionHandler. Den fångar undantag som inte har hanterats inuti korutinen och möjliggör loggning av felet utan att applikationen kraschar.
I Android används launch överallt: från ViewModel till WorkManager. Huvudmönstret är att använda lifecycleScope i Fragment och viewModelScope i ViewModel för automatisk annullering av korutiner vid slutet av komponentens livscykel.
class ProfileViewModel : ViewModel() {
private val repository = UserRepository()
fun loadProfile(userId: String) {
viewModelScope.launch(Dispatchers.IO) {
val profile = repository.fetchProfile(userId)
withContext(Dispatchers.Main) {
_profileState.update { it.copy(profile = profile) }
}
}
}
}
viewModelScope annullerar automatiskt korutiner när ViewModel förstörs. Detta eliminerar minnesläckor och garanterar att bakgrundsoperationer inte fortsätter efter förlust av kontext. Dessutom kan withContext användas för att växla mellan dispatchers.
Vanliga frågor
launch returnerar Job och returnerar inget exekveringsresultat, medan async returnerar Deferred<T> för att få resultatet. launch används för fire-and-forget-operationer, async — när du behöver vänta på och använda det returnerade värdet.
Anropa job.cancel() på det sparade Job-objektet. För gruppannullering, annullera hela CoroutineScope via scope.cancel(). Korutinen måste vara kooperativ — kontrollera isActive eller använda kontrollerbara suspend-funktioner.
Använd try-catch inuti launch-blocket eller skicka CoroutineExceptionHandler i CoroutineContext. För felisolering, använd SupervisorJob — då annullerar ett undantag i en underordnad korutin inte de andra.
Nej, launch är en tilläggsfunktion av CoroutineScope. Utan scope kan korutinen inte följa principen om strukturerad samtidighet. Använd GlobalScope.launch med försiktighet — detta skapar en korutin utan bindning till livscykeln.
Antalet begränsas av dispatcherns trådpool. Dispatchers.Default använder ett antal trådar som är lika med antalet CPU-kärnor. Dispatchers.IO stöder upp till 64 trådar. När fler korutiner startas sätts de i kö.
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å