onDestroy — metode akhir siklus hidup Activity dan Fragment di Android, dipanggil sebelum penghancuran total komponen. onDestroy menandakan bahwa Activity atau Fragment mengakhiri kerjanya: semua sumber daya harus dibebaskan, fragment bersarang — dihancurkan, ViewModel — dibersihkan. Menurut data Google, onDestroy dipanggil dalam 100% kasus penghentian Activity, tetapi saat pembunuhan proses (process death) sistem dapat melewatkan panggilan onDestroy sepenuhnya. Dokumentasi Android tentang onDestroy menekankan bahwa metode ini tidak menjamin panggilan saat penghentian darurat.
Poin Utama
onDestroy — metode callback yang dipanggil Android sebelum menghancurkan Activity atau Fragment secara final. Ini adalah kesempatan terakhir bagi pengembang untuk membebaskan sumber daya, membatalkan operasi latar belakang, dan mengakhiri pekerjaan dengan data. Setelah eksekusi onDestroy, instance Activity/Fragment ditandai untuk pengumpulan sampah (GC) dan tidak dapat digunakan lagi.
Alasan pemanggilan onDestroy:
Menurut statistik Google Android Vitals (2025), sekitar 12% dari semua kasus penghancuran Activity disebabkan oleh rotasi layar, 65% oleh finish() dan 23% oleh perubahan konfigurasi. Persentase pembunuhan proses dengan melewatkan onDestroy adalah sekitar 5–8% tergantung pada perangkat dengan RAM kecil (kurang dari 4 GB).
onDestroy dipanggil dalam sebagian besar skenario standar, tetapi ada pengecualian penting yang harus diperhatikan pengembang. Memahami jaminan panggilan onDestroy sangat penting untuk arsitektur aplikasi, terutama untuk menyimpan data dan membatalkan tugas WorkManager.
Kapan onDestroy dipanggil:
Kapan onDestroy TIDAK dipanggil:
Karena tidak adanya jaminan panggilan onDestroy, Google merekomendasikan: jangan pernah mengandalkan onDestroy untuk menyimpan data kritis. Gunakan onSaveInstanceState(), WorkManager, atau Room dengan penyimpanan otomatis. onDestroy — untuk membebaskan sumber daya, bukan untuk persistensi.
onDestroy ada baik untuk Activity maupun Fragment, tetapi dengan kontrak yang berbeda. Pada Fragment, siklus hidup lebih detail: selain onDestroy ada onDestroyView (penghancuran hierarki View) dan onDetach (pemisahan dari Activity).
| Komponen | Metode penghancuran | Urutan | ViewModel bertahan |
|---|---|---|---|
| Activity | onDestroy | onPause → onStop → onDestroy | Tidak (hanya jika ViewModelStore tidak disimpan) |
| Fragment | onDestroyView, onDestroy, onDetach | onPause → onStop → onDestroyView → onDestroy → onDetach | Ya, jika Fragment tidak dihapus |
Perbedaan utama: pada Fragment, View dibuat ulang lebih sering daripada Fragment itu sendiri. Saat rotasi layar, Fragment melalui onDestroyView (penghancuran View), tetapi Fragment itu sendiri dan ViewModel-nya tetap hidup. onDestroyView — tempat yang tepat untuk membersihkan referensi ke View untuk menghindari kebocoran memori. onDestroy Fragment — analog dengan onDestroy Activity, dipanggil saat penghapusan total Fragment.
Fragment bersarang (child fragments) dihancurkan sebelum onDestroy Fragment induk. Di Activity, fragment anak menerima onDestroy saat panggilan onDestroy Activity induk. Urutan dijamin: fragment berakhir lebih awal daripada Activity yang menampungnya.
onDestroy ditujukan untuk membebaskan semua sumber daya yang tidak boleh hidup lebih lama dari Activity atau Fragment. Berbeda dengan onStop yang membebaskan sumber daya hingga kembali, onDestroy melakukan pembersihan akhir.
Daftar periksa tindakan wajib di onDestroy:
Apa yang TIDAK boleh dilakukan di onDestroy: Jangan simpan data di onDestroy — gunakan onPause atau onSaveInstanceState. Jangan mulai Service atau tugas WorkManager baru — Activity akan dihancurkan dan Anda tidak dapat melacak hasilnya. Jangan mencoba memperbarui UI — hierarki View sudah dihancurkan atau dalam proses penghancuran; panggilan findViewById() akan mengembalikan null.
ViewModel dirancang untuk bertahan dari onDestroy Activity saat rotasi layar, tetapi dihancurkan bersama Activity saat finish(). Perilaku asimetris ini — penyebab utama kebingungan di kalangan pengembang.
Saat rotasi layar:
Saat finish() (pengguna menekan "Kembali"):
Oleh karena itu, pembatalan viewModelScope di onDestroy tidak diperlukan — ViewModel akan melakukannya sendiri. Jika Anda menggunakan lifecycleScope (terikat ke Activity, bukan ke ViewModel), batalkan di onDestroy melalui lifecycleScope.cancel() atau kelola Job secara manual.
Menunjukkan manajemen lifecycleScope yang benar di Activity: coroutine dijalankan untuk melacak status jaringan dan dibatalkan di onDestroy.
class NetworkMonitorActivity : AppCompatActivity() {
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
Log.d("NetworkMonitor", "Jaringan tersedia")
}
override fun onLost(network: Network) {
Log.d("NetworkMonitor", "Jaringan hilang")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_network)
val connectivityManager = getSystemService(ConnectivityManager::class.java)
connectivityManager.registerDefaultNetworkCallback(networkCallback)
lifecycleScope.launch {
Log.d("NetworkMonitor", "Pemantauan jaringan dimulai")
}
}
override fun onDestroy() {
super.onDestroy()
val connectivityManager = getSystemService(ConnectivityManager::class.java)
connectivityManager.unregisterNetworkCallback(networkCallback)
Log.d("NetworkMonitor", "onDestroy: callback dibatalkan")
}
}
Di onDestroy, pendaftaran callback jaringan dibatalkan. lifecycleScope dibatalkan secara otomatis saat penghancuran siklus hidup — pembatalan terpisah coroutine tidak diperlukan. Callback jaringan harus berhenti berlangganan, jika tidak akan tetap ada di sistem bahkan setelah penghancuran Activity.
Fragment membersihkan referensi ke View dengan benar di onDestroyView, mencegah kebocoran memori yang disebabkan oleh penutupan.
class ProfileFragment : Fragment() {
private var avatarView: ImageView? = null
private var progressBar: ProgressBar? = null
private val imageLoader = ImageLoader()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
avatarView = view.findViewById(R.id.avatar)
progressBar = view.findViewById(R.id.progress)
loadProfile()
}
private fun loadProfile() {
viewLifecycleOwner.lifecycleScope.launch {
try {
progressBar?.visibility = View.VISIBLE
val bitmap = imageLoader.load("https://example.com/avatar.png")
avatarView?.setImageBitmap(bitmap)
} finally {
progressBar?.visibility = View.GONE
}
}
}
override fun onDestroyView() {
super.onDestroyView()
avatarView = null
progressBar = null
imageLoader.cancel()
}
override fun onDestroy() {
super.onDestroy()
Log.d("ProfileFragment", "onDestroy: Fragment sepenuhnya dihancurkan")
}
}
Di onDestroyView, referensi ke View diatur ke nol — ini mencegah kebocoran memori jika penutupan di imageLoader menahan referensi ke avatarView. Fragment itu sendiri dan ViewModel-nya tetap hidup hingga onDestroy. imageLoader.cancel() membatalkan pemuatan jika Fragment meninggalkan layar.
Penggunaan isFinishing() memungkinkan membedakan apakah Activity berakhir atas perintah pengguna atau untuk pembuatan ulang.
class AnalyticsActivity : AppCompatActivity() {
private val analytics = Analytics()
override fun onDestroy() {
if (isFinishing) {
Log.d("AnalyticsActivity", "Activity berakhir dengan finish() — mengirim analitik")
analytics.sendSessionEnd()
} else {
Log.d("AnalyticsActivity", "Activity dibuat ulang (rotasi/konfigurasi) — tidak mengirim analitik")
}
super.onDestroy()
}
}
Pemeriksaan isFinishing() — pola penting untuk analitik, pencatatan, dan pembersihan data sesi. Saat rotasi, tidak perlu mengirim peristiwa akhir sesi — pengguna masih bekerja dengan aplikasi. Menurut Google Analytics, pemeriksaan isFinishing() yang salah adalah penyebab 40% peristiwa sesi palsu.
Pertanyaan yang Sering Diajukan
Ya, bisa — saat pembunuhan proses oleh sistem (process death), Force Stop oleh pengguna atau penghentian darurat. Menurut data Google, sekitar 5–8% penghentian Activity terjadi tanpa panggilan onDestroy. Pengembang tidak boleh mengandalkan onDestroy untuk menyimpan data kritis — gunakan onPause atau onSaveInstanceState.
finish() — panggilan yang memulai penghancuran Activity. onDestroy — callback yang dipanggil selama proses eksekusi finish(). finish() wajib untuk memanggil onDestroy pada penghentian normal. finish() dapat dipanggil oleh sistem atau pengembang, onDestroy — hanya callback sistem.
Ya, wajib baik di Activity maupun di Fragment. super.onDestroy() memastikan pembersihan yang benar dari ChildFragmentManager, LoaderManager dan komponen sistem lainnya. Melewatkan super.onDestroy() menyebabkan kebocoran memori dan bug dalam pemulihan fragment.
onCleared() dipanggil setelah onDestroy Activity atau Fragment, saat ViewModel tidak lagi diperlukan. Saat rotasi layar, onCleared() tidak dipanggil — ViewModel bertahan dari onDestroy. Urutan: onDestroy Activity/Fragment → (ViewModelStore dibersihkan) → onCleared().
Secara teknis ya, tetapi tidak disarankan. Activity segera dihancurkan setelah onDestroy dan Service yang dimulai tetap tanpa kontrol. Untuk tugas latar belakang, gunakan WorkManager dengan penundaan: WorkManager menjamin eksekusi bahkan setelah penghentian Activity dan bertahan dari process death.
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