launch — Coroutine Builder di Kotlin yang memulai coroutine tanpa mengembalikan hasil, mengembalikan objek Job untuk mengelola eksekusi. Builder ini mengimplementasikan pola fire-and-forget: coroutine mulai bekerja di thread latar belakang dan berakhir secara otomatis. Menurut dokumentasi JetBrains, 2024, launch adalah cara utama untuk memulai tugas paralel di Kotlin Coroutines.
Poin Utama
launch — adalah fungsi ekstensi Kotlin, tersedia melalui import kotlinx.coroutines, yang membuat coroutine baru dalam CoroutineScope yang ditentukan. Berbeda dengan fungsi biasa, kode di dalam launch dieksekusi secara konkuren — coroutine dapat ditangguhkan (suspend) tanpa memblokir thread dan dilanjutkan nanti.
Builder launch adalah blok bangunan fundamental dari model coroutine Kotlin. Ia tidak mengembalikan nilai yang dihitung, tetapi mengembalikan objek Job yang memungkinkan kontrol eksekusi coroutine. Semua coroutine anak yang dimulai melalui launch di dalam coroutine lain terikat pada induknya.
Builder launch didefinisikan sebagai fungsi inline dengan beberapa parameter: CoroutineScope, CoroutineContext, CoroutineStart, dan suspend-block. Parameter memiliki nilai default, membuat launch nyaman untuk skenario umum.
public fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job
Parameter context menerima CoroutineContext yang menggabungkan dispatcher, penangan exception, dan elemen bernama. Paling sering Dispatchers.IO, Dispatchers.Main, atau SupervisorJob untuk isolasi kesalahan dikirimkan.
Job — objek yang dikembalikan yang mewakili siklus hidup coroutine. Job dapat berada dalam status: New, Active, Completing, Completed, Cancelling, Cancelled. Setiap status mencerminkan status eksekusi dan memungkinkan reaksi terhadap perubahan.
val job = CoroutineScope(Dispatchers.IO).launch {
repeat(10) { i ->
delay(1000L)
println("Progres: $i")
}
}
println("Job aktif: ${job.isActive}")
delay(2500L)
job.cancel()
println("Job dibatalkan: ${job.isCancelled}")
Job mendukung hierarki: jika coroutine induk dibatalkan, semua coroutine anak akan dibatalkan secara otomatis. SupervisorJob mengubah perilaku ini — coroutine anak tidak dibatalkan ketika salah satu dari mereka mengalami kesalahan.
Konkurensi terstruktur berarti setiap coroutine dimulai dalam CoroutineScope tertentu, dan scope tidak akan selesai sampai semua coroutine anak menyelesaikan pekerjaannya. launch sepenuhnya mendukung prinsip ini — coroutine yang dimulai di dalam coroutine lain adalah anak-anaknya.
Saat launch bersarang, terbentuk pohon coroutine. Coroutine induk menunggu penyelesaian semua anak, yang menjamin urutan eksekusi yang dapat diprediksi dan menyederhanakan manajemen sumber daya.
fun main() = runBlocking {
launch {
launch {
delay(1000L)
println("Anak 1 selesai")
}
launch {
delay(500L)
println("Anak 2 selesai")
}
println("Semua anak selesai sebelum baris ini")
}
}
Perilaku ini berbeda dari konkurensi berbasis thread, di mana thread anak tidak terikat pada thread induk. Di coroutine, induk tidak selesai sampai semua anak menyelesaikan pekerjaannya.
Penanganan exception di launch tergantung pada tipe Job. Untuk Job biasa, exception menyebar ke coroutine induk dan membatalkannya. Untuk SupervisorJob atau SupervisorScope, exception diisolasi — kesalahan satu coroutine anak tidak mempengaruhi yang lain.
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
scope.launch {
try {
riskyOperation()
} catch (e: Exception) {
println("Ditangkap: ${e.message}")
}
}
scope.launch {
println("Ini masih berjalan berkat SupervisorJob")
}
Untuk penanganan global exception yang tidak tertangkap, digunakan CoroutineExceptionHandler. Ia menangkap exception yang tidak ditangani di dalam coroutine dan memungkinkan pencatatan kesalahan tanpa crash aplikasi.
Di Android, launch diterapkan di mana-mana: dari ViewModel hingga WorkManager. Pola utamanya adalah penggunaan lifecycleScope di Fragment dan viewModelScope di ViewModel untuk pembatalan otomatis coroutine saat siklus hidup komponen berakhir.
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 secara otomatis membatalkan coroutine saat ViewModel dihancurkan. Ini menghilangkan kebocoran memori dan memastikan operasi latar belakang tidak berlanjut setelah kehilangan konteks. Selain itu, withContext dapat digunakan untuk beralih antar dispatcher.
Pertanyaan yang Sering Diajukan
launch mengembalikan Job dan tidak mengembalikan hasil eksekusi, sedangkan async mengembalikan Deferred<T> untuk mendapatkan hasil. launch digunakan untuk operasi fire-and-forget, async — ketika Anda perlu menunggu dan menggunakan nilai yang dikembalikan.
Panggil job.cancel() pada objek Job yang disimpan. Untuk pembatalan grup, batalkan seluruh CoroutineScope melalui scope.cancel(). Coroutine harus kooperatif — memeriksa isActive atau menggunakan fungsi suspend yang dapat diperiksa.
Gunakan try-catch di dalam blok launch atau kirimkan CoroutineExceptionHandler di CoroutineContext. Untuk isolasi kesalahan, gunakan SupervisorJob — maka exception di satu coroutine anak tidak akan membatalkan yang lain.
Tidak, launch adalah fungsi ekstensi dari CoroutineScope. Tanpa scope, coroutine tidak dapat mengikuti prinsip konkurensi terstruktur. Gunakan GlobalScope.launch dengan hati-hati — ini menciptakan coroutine tanpa keterikatan pada siklus hidup.
Jumlahnya dibatasi oleh kumpulan thread dispatcher. Dispatchers.Default menggunakan jumlah thread yang sama dengan jumlah inti CPU. Dispatchers.IO mendukung hingga 64 thread. Saat menjalankan lebih banyak coroutine, mereka akan diantrekan.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga