Coroutine Builder — fungsi Kotlin Coroutines yang membuat dan menjalankan coroutine, menentukan cara eksekusinya. Builder launch, async, runBlocking, dan produce mencakup berbagai skenario: dari tugas latar belakang hingga komputasi paralel dengan pengembalian hasil. Menurut data JetBrains, 2024, Coroutine Builder adalah dasar dari model coroutine, menyediakan konkurensi terstruktur dan manajemen siklus hidup.
Poin Penting
Coroutine Builder — adalah fungsi ekstensi Kotlin yang menerima CoroutineScope dan suspend-block, membuat dan menjalankan coroutine baru. Setiap builder menentukan bagaimana coroutine akan dieksekusi: dengan atau tanpa pengembalian hasil, dengan memblokir thread atau secara asinkron. Builder adalah titik masuk ke model coroutine dalam bahasa ini.
Semua builder bekerja melalui CoroutineScope, yang mengelola siklus hidup coroutine anak. Ketika scope dibatalkan, semua coroutine yang dijalankan melaluinya akan dibatalkan secara otomatis — ini adalah prinsip konkurensi terstruktur. Pendekatan ini mencegah kebocoran coroutine dan menjamin penyelesaian yang dapat diprediksi.
import kotlinx.coroutines.*
fun main() = runBlocking {
// Builder bekerja di dalam CoroutineScope
val job = launch {
delay(1000L)
println("Dunia!")
}
println("Halo,")
job.join()
}
Kotlin menyediakan empat builder coroutine bawaan: launch, async, runBlocking, dan produce. Masing-masing memiliki tipe kembalian dan area penerapan sendiri. Untuk pengembangan mobile Android, yang utama adalah launch dan async — mereka bekerja secara non-blocking dan terintegrasi dengan komponen arsitektur.
| Builder | Tipe Kembalian | Pemblokiran Thread | Skenario |
|---|---|---|---|
| launch | Job | Tidak | Tugas fire-and-forget |
| async | Deferred<T> | Tidak | Komputasi paralel |
| runBlocking | T | Ya | Pengujian, fungsi main |
| produce | ReceiveChannel<E> | Tidak | Transmisi streaming (deprecated) |
Setiap builder menerima parameter tambahan: CoroutineStart (strategi eksekusi), CoroutineContext (dispatcher, pengecualian) dan blok kode bernama. Secara default, coroutine dijalankan segera (CoroutineStart.DEFAULT).
launch — builder yang paling sering digunakan dalam pengembangan Android. Builder ini menjalankan coroutine yang tidak mengembalikan hasil dan mengembalikan objek Job untuk mengelola siklus hidupnya. Ini adalah pilihan ideal untuk operasi yang hanya membutuhkan efek samping: penyimpanan ke database, pengiriman analitik, pembaruan UI.
Builder launch menerima CoroutineScope, CoroutineContext opsional, dan suspend-block. Job yang dikembalikan memungkinkan pembatalan coroutine, menunggu penyelesaiannya, atau memeriksa status.
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
val job: Job = scope.launch(CoroutineStart.LAZY) {
val data = fetchFromNetwork()
saveToDatabase(data)
}
job.start()
job.join()
Parameter CoroutineStart.LAZY menunda eksekusi hingga pemanggilan eksplisit start() atau join(). Ini berguna untuk inisialisasi yang ditunda dan eksekusi bersyarat. Untuk eksekusi langsung standar, gunakan CoroutineStart.DEFAULT atau parameter dihilangkan.
async — builder yang mengembalikan Deferred<T> — janji asinkron dari hasil. Pemanggilan await() menangguhkan coroutine hingga hasil diperoleh, tanpa memblokir thread. Ini adalah mekanisme utama untuk tugas paralel dalam coroutine Kotlin.
async sangat efektif ketika beberapa operasi independen perlu dilakukan secara bersamaan. Berbeda dengan pemanggilan berurutan fungsi suspend, async menjalankan coroutine secara paralel, memperpendek total waktu eksekusi.
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 mewarisi dari Job, sehingga async mendukung semua operasi siklus hidup: pembatalan, menunggu penyelesaian, penanganan pengecualian. Ketika scope dibatalkan, coroutine anak Deferred dibatalkan secara otomatis.
runBlocking — satu-satunya builder yang memblokir thread saat ini hingga coroutine selesai. Builder ini membuat CoroutineScope baru dan menjalankan coroutine yang diberikan, memblokir thread pemanggil. Digunakan di titik masuk main(), dalam pengujian, dan saat integrasi dengan kode blocking.
runBlocking dibenarkan dalam tiga skenario: titik masuk aplikasi (main), pengujian unit fungsi suspend, dan integrasi dengan pustaka berbasis callback di mana suspend tidak dapat digunakan. Dalam kode produksi Android, penggunaan runBlocking pada thread utama sangat tidak disarankan.
class CoroutineTest {
@Test
fun `test suspend function`() = runBlocking {
val result = mySuspendFunction()
assertEquals("expected", result)
}
}
Untuk pengujian, disarankan menggunakan kotlinx-coroutines-test dengan TestCoroutineDispatcher daripada runBlocking — ini memberikan kontrol waktu dan menghindari pemblokiran di lingkungan pengujian.
Pemilihan Coroutine Builder tergantung pada hasil kembalian dan skenario eksekusi. Jika operasi tidak memerlukan pengembalian data — gunakan launch. Jika hasil operasi asinkron diperlukan — async. runBlocking terapkan hanya untuk bridging, dan produce ganti dengan Flow untuk aliran reaktif.
Dalam proyek Android yang menggunakan Kotlin Coroutines, pasangan utama builder adalah launch dan async. launch digunakan di ViewModel dan UseCases untuk menjalankan coroutine, sedangkan async — untuk permintaan paralel ke jaringan atau database. Pustaka modern (Ktor, Room) sudah mendukung fungsi suspend, yang meminimalkan kebutuhan penggunaan async secara langsung.
Pertanyaan yang Sering Diajukan
launch mengembalikan Job dan tidak mengembalikan hasil eksekusi, sedangkan async mengembalikan Deferred<T> — objek dari mana hasil dapat diperoleh melalui await(). launch digunakan untuk operasi fire-and-forget, async — untuk tugas yang mengembalikan data.
Tidak disarankan. runBlocking pada thread utama menyebabkan ANR dan memblokir UI. Gunakan lifecycleScope.launch di dalam Activity dan Fragment — ini adalah solusi bawaan tanpa pemblokiran.
Builder launch mengembalikan objek Job yang memungkinkan Anda mengontrol siklus hidup coroutine: membatalkan (cancel), menunggu penyelesaian (join), memeriksa status (isActive, isCompleted, isCancelled).
Deferred<T> — adalah janji asinkron dari hasil, dikembalikan oleh builder async. Deferred mewarisi dari Job dan menambahkan metode await() untuk memperoleh hasil, getCompleted() untuk akses non-blocking, dan getCompletionExceptionOrNull() untuk memeriksa pengecualian.
Gunakan parameter CoroutineStart.LAZY: scope.launch(start = CoroutineStart.LAZY) { ... }. Kemudian panggil job.start() atau job.join() untuk eksekusi aktual. Ini berguna untuk inisialisasi yang ditunda dan eksekusi bersyarat coroutine.
Kesimpulan
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