LifecycleOwner — adalah antarmuka kunci dari pustaka Android Jetpack yang mendeklarasikan bahwa sebuah objek memiliki siklus hidup dan menyediakan akses ke sana melalui metode getLifecycle(). Ini terletak di dasar arsitektur komponen aplikasi Android modern, memungkinkan pemisahan logika kerja dengan siklus hidup dari implementasi konkret Activity atau Fragment. Menurut data Google I/O 2024, lebih dari 85% proyek baru di Android menggunakan LifecycleOwner untuk mengelola langganan dan mencegah kebocoran memori. Antarmuka ini merupakan fondasi untuk LiveData, ViewModel, dan komponen Jetpack lainnya, memastikan eksekusi kode yang aman hanya dalam keadaan aktif komponen.
Poin utama
LifecycleOwner — adalah antarmuka dari paket androidx.lifecycle yang berisi satu metode getLifecycle(), yang mengembalikan objek Lifecycle. Objek ini melacak status saat ini komponen (CREATED, STARTED, RESUMED, DESTROYED) dan memberi tahu semua pengamat yang berlangganan saat perubahannya. LifecycleOwner adalah bagian dari Architecture Components dan termasuk dalam pustaka lifecycle-runtime.
Tugas utama antarmuka adalah menstandarisasi akses ke siklus hidup. Sebelum munculnya Jetpack, pengembang menggunakan langganan manual di onStart dan berhenti berlangganan di onStop, yang menyebabkan duplikasi kode dan kesalahan. LifecycleOwner memecahkan masalah ini dengan menyediakan mekanisme terpadu untuk semua komponen Android. Alih-alih memanggil metode siklus hidup secara eksplisit, pengembang berlangganan ke Lifecycle sekali, dan pemberitahuan datang secara otomatis.
Antarmuka dideklarasikan di Kotlin sebagai antarmuka fungsional dengan satu metode abstrak:
interface LifecycleOwner {
val lifecycle: Lifecycle
}
Berkat sifat fungsional antarmuka, mudah untuk diimplementasikan menggunakan delegasi atau lambda. Ini sangat nyaman untuk membuat Custom Views dan kelas ViewModel yang harus bereaksi terhadap perubahan siklus hidup host. Objek Lifecycle yang diperoleh dari getLifecycle() menyediakan metode addObserver dan removeObserver untuk mengelola langganan.
LifecycleOwner bekerja bersama dengan dua kelas kunci: Lifecycle dan LifecycleObserver. Lifecycle menyimpan status saat ini komponen dalam bentuk enum State (INITIALIZED, CREATED, STARTED, RESUMED, DESTROYED) dan melacak transisi di antaranya. Saat status berubah, Lifecycle memberi tahu semua pengamat yang terdaftar, memanggil metode yang dianotasi sesuai. Mekanisme ini disebut "lifecycle-aware" — kode hanya dijalankan ketika komponen berada dalam status yang sesuai.
Mekanisme transmisi acara didasarkan pada pola Observer. LifecycleOwner berperan sebagai Observable, dan implementasi LifecycleObserver berperan sebagai Observer. Activity atau Fragment saat mengubah statusnya (onCreate → onStart → onResume → onPause → onStop → onDestroy) memberi tahu Lifecycle melalui mekanisme internal ReportFragment, yang secara otomatis ditambahkan ke sistem AndroidX. Pengembang tidak perlu memanggil metode Lifecycle secara manual — semuanya terjadi secara otomatis.
| Status Lifecycle | Acara | Metode siklus hidup Android |
|---|---|---|
| INITIALIZED | — | Sebelum onCreate |
| CREATED | ON_CREATE | onCreate |
| STARTED | ON_START | onStart |
| RESUMED | ON_RESUME | onResume |
| STARTED | ON_PAUSE | onPause |
| CREATED | ON_STOP | onStop |
| DESTROYED | ON_DESTROY | onDestroy |
Detail penting: Lifecycle menjamin bahwa acara ON_STOP dan ON_DESTROY akan dikirimkan bahkan dalam kasus penghentian proses yang tidak normal. Ini menjadikan LifecycleOwner alat yang andal untuk membebaskan sumber daya kritis. Untuk penyimpanan status biasa, disarankan menggunakan SavedStateHandle di ViewModel, tetapi LifecycleOwner menyediakan tingkat keamanan dasar.
Ada dua cara untuk berlangganan acara LifecycleOwner: LifecycleObserver klasik dengan anotasi dan DefaultLifecycleObserver modern dengan metode eksplisit. Pendekatan kedua direkomendasikan oleh Google sejak 2022, karena memberikan keamanan tipe yang lebih baik dan menghindari refleksi yang digunakan dalam pendekatan anotasi. DefaultLifecycleObserver memerlukan Java 8+ atau Kotlin dan lebih disukai untuk proyek baru.
Contoh berlangganan melalui DefaultLifecycleObserver:
class MyObserver : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
// Memulai pelacakan GPS hanya ketika komponen aktif
startLocationUpdates()
}
override fun onStop(owner: LifecycleOwner) {
// Penghentian aman saat beralih ke mode latar belakang
stopLocationUpdates()
}
}
// Koneksi:
lifecycleOwner.lifecycle.addObserver(MyObserver())
Setiap metode DefaultLifecycleObserver menerima LifecycleOwner sebagai parameter. Ini memungkinkan pengamat mengakses konteks komponen yang sedang dijalankan tanpa perlu meneruskannya secara terpisah. Pendekatan ini membuat kode lebih modular dan dapat diuji — Observer tidak bergantung pada implementasi konkret Activity atau Fragment, tetapi bekerja dengan abstraksi LifecycleOwner.
Cara lama dengan menggunakan anotasi @OnLifecycleEvent masih ditemukan di proyek lama, tetapi penggunaannya tidak disarankan untuk kode baru. Refleksi yang diperlukan untuk memproses anotasi menambah overhead dan dapat menyebabkan kesalahan yang tidak terdeteksi pada tahap kompilasi. Google secara resmi merekomendasikan migrasi ke DefaultLifecycleObserver.
// Pendekatan usang — tidak disarankan untuk proyek baru
class MyLegacyObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onStart() {
startLocationUpdates()
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onStop() {
stopLocationUpdates()
}
}
Pendekatan anotasi memiliki kekurangan signifikan: kurangnya kontrol masa hidup Observer. Jika pengembang lupa berhenti berlangganan Observer saat LifecycleOwner dihancurkan, objek Observer tetap berada di memori hingga pengumpul sampah dipanggil. DefaultLifecycleObserver memecahkan masalah ini — Observer terikat ke Lifecycle dan secara otomatis berhenti berlangganan saat transisi ke status DESTROYED.
Mulai dari AppCompat 1.1.0 dan AndroidX Fragment 1.2.0, semua Activity dan Fragment yang mewarisi AppCompatActivity atau Fragment secara otomatis adalah LifecycleOwner. Ini berarti metode getLifecycle() tersedia di dalamnya secara default, dan berlangganan acara siklus hidup berfungsi tanpa konfigurasi tambahan. Pengembang cukup memanggil lifecycle.addObserver() dari mana saja di Activity atau Fragment.
Mari kita lihat contoh integrasi LifecycleOwner di Activity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycle.addObserver(LocationObserver(this))
}
}
Dalam contoh ini lifecycle adalah extension property, tersedia berkat AndroidX Activity. Observer LocationObserver akan secara otomatis menerima pemberitahuan tentang mulai (ON_START) dan berhenti (ON_STOP) Activity. Saat rotasi layar, Observer diberi tahu tentang ON_DESTROY dan kemudian ON_CREATE, yang memungkinkan penanganan perubahan konfigurasi dengan benar tanpa kode tambahan.
Fragment mengimplementasikan LifecycleOwner melalui antarmuka, dan Lifecycle-nya terikat pada siklus hidup Fragment, bukan Activity induk. Ini penting: Lifecycle Fragment masuk ke DESTROYED saat Fragment dihapus dari transaksi, sementara Activity dapat tetap dalam RESUMED. Perbedaan ini memungkinkan Observer untuk berlangganan secara terpisah pada siklus hidup setiap komponen.
class MyFragment : Fragment() {
private val uiStateObserver = UiStateObserver()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
lifecycle.addObserver(uiStateObserver)
}
}
Keuntungan penting menggunakan LifecycleOwner di Fragment adalah berhenti berlangganan otomatis saat Fragment masuk ke DESTROYED. Ini sangat relevan untuk ViewPager, di mana Fragment dapat dibuat dan dihancurkan secara dinamis. Manajemen langganan manual dalam skenario ini akan sangat kompleks dan rentan terhadap kesalahan.
Antarmuka LifecycleOwner dapat diimplementasikan di kelas mana pun yang memiliki siklus hidup. Ini berguna untuk Custom Views, Service, dan bahkan ViewModel dalam beberapa solusi arsitektur. Google menyediakan kelas pembantu LifecycleRegistry yang mengelola status Lifecycle dan menghasilkan acara. Pengembang perlu memanggil secara manual metode yang sesuai dari LifecycleRegistry saat perubahan status komponen.
Contoh implementasi LifecycleOwner di Custom View:
class MyCustomView(
context: Context,
attrs: AttributeSet?
) : FrameLayout(context, attrs), LifecycleOwner {
private val lifecycleRegistry = LifecycleRegistry(this)
override val lifecycle: Lifecycle
get() = lifecycleRegistry
fun onStart() {
lifecycleRegistry.setCurrentState(Lifecycle.State.STARTED)
}
fun onStop() {
lifecycleRegistry.setCurrentState(Lifecycle.State.CREATED)
}
}
Dalam contoh ini LifecycleRegistry berperan sebagai penyimpan status. Metode onStart/onStop harus dipanggil oleh komponen induk (misalnya, Activity) saat Custom View menjadi terlihat atau tersembunyi. LifecycleRegistry secara otomatis menghitung acara yang diperlukan untuk transisi antar status dan memberi tahu semua Observer yang berlangganan.
Saat mengimplementasikan LifecycleOwner kustom, penting untuk mengikuti aturan: status LifecycleRegistry harus diperbarui terakhir dalam metode siklus hidup yang sesuai, setelah semua operasi lainnya. Ini menjamin bahwa Observer menerima pemberitahuan ketika komponen sudah sepenuhnya siap untuk status baru. Penggunaan LifecycleRegistry.createUnsafe sebagai alternatif juga dimungkinkan, tetapi memerlukan kehati-hatian dengan utas.
LifecycleOwner adalah fondasi untuk beberapa komponen kunci Android Jetpack. LiveData menggunakan LifecycleOwner untuk menentukan status aktif dan berhenti berlangganan secara otomatis saat komponen dihancurkan. ViewModel tidak mengimplementasikan LifecycleOwner secara langsung, tetapi dapat menerima Lifecycle melalui SavedStateHandle. Navigation Component menggunakan LifecycleOwner untuk mengelola langganan di NavBackStackEntry. Memahami hubungan ini membantu membangun arsitektur aplikasi di atas fondasi yang kokoh.
Interaksi LiveData dengan LifecycleOwner:
class ExampleActivity : AppCompatActivity() {
private val viewModel: ExampleViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.userData.observe(this) { data ->
// this — LifecycleOwner (Activity)
// Kode hanya dijalankan ketika Activity dalam status RESUMED
updateUI(data)
}
}
}
LiveData memerlukan LifecycleOwner dalam metode observe() karena ini menjamin bahwa pembaruan UI hanya akan terjadi dalam status aktif. Jika Activity berada di latar belakang, LiveData menyimpan nilai terakhir tetapi tidak memberi tahu Observer. Saat kembali ke RESUMED, Observer menerima nilai terkini tanpa permintaan tambahan ke jaringan atau basis data.
DataBinding juga menggunakan LifecycleOwner untuk mengikat bidang observable ke siklus hidup Activity atau Fragment. Ini memungkinkan pencegahan kebocoran memori dalam kombinasi ViewModel + DataBinding — semua langganan secara otomatis dibersihkan saat LifecycleOwner dihancurkan. Pendekatan ini membuat kode deklaratif dan aman.
Penggunaan LifecycleOwner yang benar memerlukan kepatuhan terhadap beberapa aturan kunci. Pertama dan terpenting: selalu berlangganan Observer di onCreate/onViewCreated, bukan nanti. Ini menjamin bahwa Observer menerima status awal Lifecycle (CREATED setelah onCreate) dan tidak melewatkan acara. Aturan kedua: gunakan DefaultLifecycleObserver daripada pendekatan anotasi untuk semua proyek baru.
Pendekatan modern untuk bekerja dengan coroutine dan LifecycleOwner — ekstensi repeatOnLifecycle:
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.flow.collect { value ->
updateUI(value)
}
}
}
Pola ini menjamin bahwa collect pada Flow hanya aktif dalam status STARTED atau RESUMED. Saat transisi ke STOPPED, koleksi secara otomatis dibatalkan, dan saat kembali ke STARTED — dimulai ulang. repeatOnLifecycle menggantikan berhenti berlangganan manual dari Flow di Fragment dan merupakan pendekatan yang direkomendasikan Google untuk bekerja dengan aliran data asinkron di komponen UI.
Satu rekomendasi penting lainnya: jangan menyalahgunakan LifecycleObserver untuk logika yang tidak terkait dengan siklus hidup. Jika komponen harus melakukan tindakan pada status tertentu tetapi tidak memerlukan berhenti berlangganan saat dihancurkan, lebih baik menggunakan pemanggilan eksplisit metode di onStart/onStop. LifecycleObserver dibenarkan untuk komponen berumur panjang (LocationListener, SensorManager), di mana manajemen langganan manual kompleks dan rentan terhadap kesalahan.
Pertanyaan yang sering diajukan
LifecycleOwner — adalah antarmuka yang menyatakan bahwa objek memiliki siklus hidup. Lifecycle — adalah kelas yang menyimpan status saat ini dan mengelola Observer. LifecycleOwner menyediakan Lifecycle melalui getLifecycle().
Tidak, Lifecycle secara otomatis berhenti berlangganan semua Observer saat transisi ke DESTROYED. Ini adalah salah satu keuntungan utama LifecycleOwner — pengembang tidak perlu memanggil removeObserver secara manual di onDestroy.
Fragment mengimplementasikan LifecycleOwner melalui antarmuka fragmen AndroidX. Lifecycle-nya terikat pada siklus hidup Fragment secara terpisah dari Activity. Ini memungkinkan Observer bereaksi pada acara Fragment, bukan Activity induk.
Ya, untuk ini digunakan LifecycleRegistry. Custom View harus mengimplementasikan antarmuka LifecycleOwner dan secara manual memperbarui status LifecycleRegistry saat visibilitas atau keterikatan ke jendela berubah.
LifecycleOwner memecahkan tugas lain: mengelola langganan acara siklus hidup, bukan pembatalan coroutine. Untuk coroutine digunakan lifecycleScope, yang secara otomatis membatalkan coroutine yang dimulai saat LifecycleOwner dihancurkan.
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