lifecycleScope — adalah CoroutineScope bawaan dari pustaka androidx.lifecycle, yang terikat pada siklus hidup Activity, Fragment, atau LifecycleOwner mana pun dan secara otomatis membatalkan korutin saat komponen dihancurkan. Menurut Google Android Developers, 2025, lifecycleScope memungkinkan menjalankan korutin yang terkait dengan lapisan UI secara aman tanpa risiko mengeksekusi kode setelah Activity atau Fragment dihancurkan. Scope secara otomatis dibatalkan saat LifecycleOwner beralih ke status DESTROYED.
Poin Utama
lifecycleScope — adalah properti ekstensi pada antarmuka LifecycleOwner (Activity, Fragment, Service) yang menyediakan CoroutineScope siap pakai yang terikat pada siklus hidup lengkap komponen. Saat LifecycleOwner mencapai status DESTROYED, lifecycleScope secara otomatis membatalkan semua korutin aktif.
// Di Fragment atau Activity
lifecycleScope.launch {
delay(1000)
showSnackbar("Halo!")
}
Tidak seperti viewModelScope, lifecycleScope dibatalkan pada setiap penghancuran LifecycleOwner — termasuk rotasi layar. Ini membuatnya ideal untuk operasi yang hanya perlu hidup selama layar tertentu terlihat.
lifecycleScope tersedia di mana pun ada LifecycleOwner:
Mekanisme pembatalan otomatis lifecycleScope didasarkan pada langganan peristiwa Lifecycle. Saat Lifecycle turun di bawah CREATED ke DESTROYED, scope dibatalkan.
| Status | Deskripsi | Scope aktif |
|---|---|---|
| CREATED | LifecycleOwner dibuat, onCreate dijalankan | Ya |
| STARTED | LifecycleOwner terlihat (onStart) | Ya |
| RESUMED | LifecycleOwner di latar depan (onResume) | Ya |
| DESTROYED | LifecycleOwner dihancurkan (onDestroy) | Tidak (scope dibatalkan) |
lifecycleScope dibuat sebagai CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) dan disimpan di dalam Lifecycle. Saat Lifecycle beralih ke status DESTROYED, scope.cancel() dipanggil. Mekanisme ini diimplementasikan melalui LifecycleEventObserver, yang berlangganan peristiwa siklus hidup saat pertama kali mengakses scope.
Saat rotasi layar, Activity dihancurkan (onDestroy) dan dibuat ulang. lifecycleScope dibatalkan bersama Activity lama, dan instance scope baru dibuat untuk Activity baru. Ini adalah perbedaan mendasar dari viewModelScope, yang dipertahankan saat rotasi.
Pustaka lifecycle menyediakan beberapa cara untuk menjalankan korutin melalui lifecycleScope. Mari kita lihat evolusi API dari metode usang ke modern.
Cara paling sederhana — lifecycleScope.launch { ... }. Korutin segera dimulai dan dibatalkan saat DESTROYED. Namun, ia dapat mengeksekusi kode bahkan ketika UI tidak terlihat (misalnya, di latar belakang setelah onStop). Ini tidak selalu diinginkan.
Metode ini menjeda eksekusi korutin saat Lifecycle turun di bawah status yang ditentukan dan melanjutkannya saat kembali. Namun, metode ini ditandai sebagai @Deprecated di lifecycle-runtime-ktx 2.6.0, karena:
repeatOnLifecycle — cara yang direkomendasikan Google untuk menjalankan korutin yang disinkronkan dengan siklus hidup. Ini membatalkan dan memulai ulang korutin setiap kali Lifecycle mencapai status yang ditentukan.
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect { state ->
updateUI(state)
}
}
}
Korutin yang diteruskan ke repeatOnLifecycle dimulai saat Lifecycle mencapai STARTED dan dibatalkan saat turun di bawah STARTED. Saat kembali ke STARTED, korutin dimulai ulang dari awal. Ini aman dan efisien — tidak ada korutin yang menggantung dalam jeda.
Untuk mengumpulkan data dari Flow dengan mempertimbangkan siklus hidup, ada operator flowWithLifecycle. Operator ini secara otomatis menghentikan dan melanjutkan pengumpulan saat status Lifecycle berubah:
viewModel.uiState
.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
.onEach { state -> updateUI(state) }
.launchIn(lifecycleScope)
Operator flowWithLifecycle — cara paling ringkas untuk berlangganan Flow dengan aman di lapisan UI.
Mari kita lihat tiga skenario nyata penggunaan lifecycleScope di aplikasi Android dalam Kotlin.
class MapFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
locationProvider.observeLocation().collect { loc ->
updateMapMarker(loc)
}
}
}
}
}
Korutin dimulai saat fragmen menjadi terlihat (STARTED) dan dibatalkan saat meninggalkan layar (STOPPED). Jika pengguna beralih ke aplikasi lain, pembaruan lokasi tidak menghabiskan baterai.
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.RESUMED) {
animateFadeIn(titleView)
delay(200)
animateSlideUp(contentView)
}
}
Animasi dimulai hanya saat fragmen di latar depan (RESUMED). Jika pengguna meminimalkan aplikasi selama animasi, korutin dibatalkan, dan saat kembali animasi dimulai ulang.
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
while (isActive) {
syncData()
delay(30_000L)
}
}
}
Data disinkronkan setiap 30 detik, tetapi hanya saat layar terlihat. isActive memeriksa apakah korutin tidak dibatalkan, memastikan keluar yang aman dari loop saat meninggalkan layar.
Kedua scope terikat pada siklus hidup, tetapi pada aspek yang berbeda. Memahami perbedaannya sangat penting untuk arsitektur aplikasi Android yang benar.
viewModelScope terikat pada ViewModel, yang bertahan dari rotasi layar. lifecycleScope terikat pada LifecycleOwner (Activity/Fragment), yang saat rotasi dihancurkan dan dibuat ulang. Ini menentukan skenario penerapannya.
Dalam praktiknya, kombinasi kedua scope sering ditemui: viewModelScope memuat data dan mengelola status, lifecycleScope berlangganan Flow dari ViewModel dengan mempertimbangkan siklus hidup layar. Pemisahan tanggung jawab ini dianggap sebagai best practice dalam pengembangan Android modern.
Mari kita lihat empat kesalahan paling umum yang dilakukan pengembang saat menggunakan lifecycleScope.
Jika Anda memulai pemuatan data di lifecycleScope.launch, saat rotasi layar korutin akan dibatalkan dan data harus dimuat ulang. Gunakan viewModelScope untuk operasi berumur panjang. lifecycleScope — hanya untuk tugas terkait UI.
Panggilan langsung viewModel.someFlow.collect { ... } di dalam lifecycleScope.launch terus mengumpulkan data bahkan saat layar tidak terlihat. Ini dapat menyebabkan pembaruan UI di latar belakang dan overhead yang tidak perlu. Selalu gunakan repeatOnLifecycle atau flowWithLifecycle.
Meskipun lifecycleScope dibatalkan saat DESTROYED, kode setelah titik jeda (suspend) mungkin tidak dijalankan saat pembatalan mendadak. Jangan mengandalkan eksekusi kode setelah panggilan suspend, kecuali jika Anda menggunakan NonCancellable.
launchWhenStarted dan analognya tidak membatalkan korutin, hanya menjedanya. Jika layar sering beralih antara latar depan dan latar belakang, korutin mengakumulasi panggilan yang ditunda. Beralihlah ke repeatOnLifecycle — ini adalah satu-satunya cara yang benar untuk sinkronisasi dengan Lifecycle.
Pertanyaan yang Sering Diajukan
lifecycleScope secara otomatis dibatalkan saat LifecycleOwner dihancurkan. GlobalScope hidup selama seluruh waktu operasi aplikasi. Korutin di lifecycleScope tidak dapat memperbarui UI setelah komponen dihancurkan, di GlobalScope dapat, yang menyebabkan kerusakan. Selalu gunakan lifecycleScope di lapisan UI.
Tidak, ViewModel bukan LifecycleOwner, jadi lifecycleScope tidak tersedia di dalamnya. ViewModel menggunakan viewModelScope. Jika kode harus dijalankan di kedua konteks — ekstrak logika ke use case atau repository dengan fungsi suspend.
Setiap panggilan repeatOnLifecycle membuat korutin baru yang menjalankan blok saat mencapai status Lifecycle yang ditentukan. Jika repeatOnLifecycle dipanggil dua kali untuk status yang sama, kedua blok akan dijalankan secara independen. Biasanya satu panggilan di onViewCreated sudah cukup.
Dispatcher lifecycleScope tidak dapat diubah secara langsung — ia menggunakan Dispatchers.Main.immediate. Di dalam blok korutin, Anda dapat beralih ke dispatcher lain melalui withContext. Untuk pengujian, gunakan TestDispatcher dengan LifecycleOwner.
lifecycleScope dibatalkan saat LifecycleOwner beralih ke status DESTROYED (setelah onDestroy). Panggilan lifecycleScope.launch sederhana tidak dibatalkan di onPause atau onStop. Untuk menjeda saat pergi ke latar belakang, gunakan repeatOnLifecycle(STARTED) atau repeatOnLifecycle(RESUMED).
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