Android Developer yang pernah develop dengan Java mungkin merasakan betapa rumit dan panjangnya kode untuk mengelola background task. perlu puluhan baris kode untuk membuat satu background task. belum lagi bisa terjebak “Callback Hell” karena background task di Java menggunakan callback. kini kotlin benar-benar makin memudahkan Android Developer dengan adanya Coroutines yang memungkinkan kita untuk membuat Background Task dengan lebih sedikit baris kode dan tanpa takut terjebak “Callback Hell”.
Apa itu Kotlin Coroutine?
Secara sederhana, Coroutine adalah “Thread ringan” (Lightweight Thread). Coroutine memungkinkan kita menulis kode asynchronous (seperti pemanggilan API atau akses database) dengan gaya penulisan sekuensial (berurutan) tanpa memblokir thread utama (Main Thread).
Berbeda dengan Thread biasa yang dikelola oleh sistem operasi dan memakan memori besar (sekitar 1MB per thread), satu Thread bisa menjalankan ribuan Coroutine sekaligus karena dikelola di level aplikasi oleh Kotlin Runtime.
Jenis-Jenis Komponen Utama Coroutine
Untuk menggunakan Coroutine secara efektif, Anda harus memahami empat pilar utamanya:
1. Coroutine Scope
Menentukan masa hidup (lifecycle) dari Coroutine.
- GlobalScope: Hidup selama aplikasi berjalan (jarang disarankan karena risiko memory leak).
- lifecycleScope / viewModelScope: Otomatis berhenti saat Activity/Fragment hancur atau ViewModel dibersihkan (sangat disarankan di Android).
- runBlocking: Memblokir thread saat ini sampai semua coroutine di dalamnya selesai (biasanya untuk unit testing).
2. Coroutine Dispatchers
Menentukan di thread mana Coroutine akan dijalankan:
- Dispatchers.Main: Untuk operasi UI di Android (mengupdate text, menampilkan dialog).
- Dispatchers.IO: Dioptimalkan untuk operasi Input/Output (Request API, baca file, Room database).
- Dispatchers.Default: Untuk komputasi berat yang memakan CPU (pengolahan gambar besar, sorting data masif).
3. Coroutine Builders
Cara untuk memulai Coroutine:
- launch: “Fire and forget”. Memulai coroutine tanpa mengembalikan hasil. Mengembalikan objek
Jobyang bisa dibatalkan. - async: Memulai coroutine dan mengembalikan hasil di masa depan melalui
Deferred<T>. Gunakan.await()untuk mengambil hasilnya.
4. Suspend Function
Fungsi yang ditandai dengan kata kunci suspend. Fungsi ini bisa menghentikan eksekusi Coroutine sementara tanpa memblokir thread, dan melanjutkannya kembali setelah tugas selesai.
Manfaat Menggunakan Coroutine
- Lighweight (Ringan): Anda bisa menjalankan 100.000 Coroutine pada satu Thread tanpa mengalami
OutOfMemoryError. - Minimal Memory Leaks: Dengan Structured Concurrency, Coroutine yang dijalankan dalam scope tertentu akan otomatis dibatalkan jika scope tersebut hancur.
- Kode Lebih Bersih: Mengubah kode asinkronus yang kompleks menjadi kode yang mudah dibaca seperti kode sinkronus biasa.
- Built-in Cancellation Support: Pembatalan tugas yang sedang berjalan sangat mudah dikelola melalui objek
Job.
Kapan Harus Menggunakan Coroutine?
Sebagai Android atau Kotlin Developer, berikut adalah skenario umum penggunaan Coroutine:
- Network Calls: Saat mengambil data dari internet menggunakan Retrofit atau Ktor. Gunakan
Dispatchers.IO. - Database Operations: Saat menyimpan atau mengambil data dari Room Database.
- Heavy Computation: Saat melakukan parsing JSON yang sangat besar atau enkripsi data. Gunakan
Dispatchers.Default. - Chaining Tasks: Misal, Anda harus mengambil ID User dari API A, lalu menggunakan ID tersebut untuk mengambil data profil dari API B. Dengan Coroutine, ini cukup ditulis dalam dua baris kode berurutan.
- Delayed Tasks: Menggunakan
delay()(bukanThread.sleep()) untuk menjalankan perintah setelah jeda waktu tertentu tanpa membekukan aplikasi.
Contoh kode
/* Menjalankan tugas di latar belakang dan update UI.
dengan Scope View Model (akan otomatis di destroy saat ViewModel tidak aktif). */
viewModelScope.launch(Dispatchers.Main) {
// 1. Tampilkan Loading
showProgressBar()
// 2. Ambil data dari API (pindah ke IO thread secara otomatis oleh library seperti Retrofit)
val result = withContext(Dispatchers.IO) {
repository.getUserData()
}
// 3. Kembali ke Main Thread untuk update UI
updateUI(result)
hideProgressBar()
}
