onDestroy — Android'de Activity ve Fragment'ın yaşam döngüsünün son yöntemi, bileşenin tamamen yok edilmesinden önce çağrılır. onDestroy, Activity veya Fragment'ın işini bitirdiğini belirtir: tüm kaynaklar serbest bırakılmalı, iç içe fragmentlar yok edilmeli, ViewModel temizlenmelidir. Google'a göre, onDestroy Activity sonlandırmalarının %100'ünde çağrılır, ancak süreç ölümü (process death) sırasında sistem onDestroy çağrısını tamamen atlayabilir. onDestroy ile ilgili Android Belgeleri, bu yöntemin anormal sonlandırmada çağrılmayı garanti etmediğini vurgular.
Önemli Noktalar
onDestroy — Android'in bir Activity veya Fragment'ı tamamen yok etmeden önce çağırdığı bir geri çağırma yöntemidir. Bu, geliştiricinin kaynakları serbest bırakması, arka plan işlemlerini iptal etmesi ve veri çalışmalarını sonlandırması için son fırsattır. onDestroy yürütüldükten sonra, Activity/Fragment örneği çöp toplama (GC) için işaretlenir ve artık kullanılamaz.
onDestroy çağrılma nedenleri:
Google Android Vitals istatistiklerine (2025) göre, tüm Activity yok etme vakalarının yaklaşık %12'si ekran döndürme nedeniyle, %65'i finish() nedeniyle ve %23'ü yapılandırma değişiklikleri nedeniyle gerçekleşir. onDestroy'un atlandığı süreç ölümü yüzdesi, düşük RAM'li (4 GB'den az) cihazlara bağlı olarak yaklaşık %5–8'dir.
onDestroy çoğu standart senaryoda çağrılır, ancak geliştiricinin dikkate alması gereken önemli istisnalar vardır. onDestroy çağrısının garantilerini anlamak, uygulama mimarisi için kritiktir, özellikle verileri kaydetmek ve WorkManager görevlerini iptal etmek için.
onDestroy ne zaman çağrılır:
onDestroy ne zaman çağrılmaz:
onDestroy çağrısı garantisinin olmaması nedeniyle Google şunları önerir: kritik verileri kaydetmek için asla onDestroy'a güvenmeyin. onSaveInstanceState(), WorkManager veya otomatik kaydetmeli Room kullanın. onDestroy kaynakları serbest bırakmak içindir, kalıcılık (persistence) için değil.
onDestroy hem Activity hem de Fragment için mevcuttur, ancak farklı sözleşmelerle. Fragment'ın yaşam döngüsü daha ayrıntılıdır: onDestroy'un yanı sıra, onDestroyView (View hiyerarşisinin yok edilmesi) ve onDetach (Activity'den ayrılma) vardır.
| Bileşen | Yok etme yöntemleri | Sıra | ViewModel hayatta kalır |
|---|---|---|---|
| Activity | onDestroy | onPause → onStop → onDestroy | Hayır (yalnızca ViewModelStore kaydedilmezse) |
| Fragment | onDestroyView, onDestroy, onDetach | onPause → onStop → onDestroyView → onDestroy → onDetach | Evet, Fragment kaldırılmazsa |
Temel fark: Bir Fragment'ın View'i, Fragment'ın kendisinden daha sık yeniden oluşturulur. Ekran döndürme sırasında, Fragment onDestroyView'den (View yok etme) geçer, ancak Fragment'ın kendisi ve ViewModel'i canlı kalır. onDestroyView, bellek sızıntılarını önlemek için View referanslarını temizlemek için doğru yerdir. Fragment'ın onDestroy'u, Fragment tamamen kaldırıldığında çağrılan Activity'nin onDestroy'una benzer.
Alt fragmentlar, üst Fragment'ın onDestroy'undan önce yok edilir. Activity'de, alt fragmentlar, üst Activity'nin onDestroy'u çağrıldığında onDestroy alır. Sıra garanti edilir: fragmentlar, onları içeren Activity'den önce sonlanır.
onDestroy, Activity veya Fragment'tan daha uzun yaşamaması gereken tüm kaynakları serbest bırakmak içindir. Geri dönene kadar kaynakları serbest bırakan onStop'un aksine, onDestroy nihai temizliği yapar.
onDestroy'de zorunlu eylemlerin kontrol listesi:
onDestroy'de ne YAPILMAMALI: onDestroy'de veri kaydetmeyin — onPause veya onSaveInstanceState kullanın. Yeni Service veya WorkManager görevleri başlatmayın — Activity yok edilecek ve sonucu takip edemezsiniz. Kullanıcı arayüzünü güncellemeye çalışmayın — View hiyerarşisi zaten yok edilmiş veya yok edilme sürecindedir; findViewById() çağırmak null döndürecektir.
ViewModel, ekran döndürme sırasında Activity'nin onDestroy'undan hayatta kalacak şekilde tasarlanmıştır, ancak finish() sırasında Activity ile birlikte yok edilir. Bu asimetrik davranış, geliştiriciler arasındaki karışıklığın ana nedenidir.
Ekran döndürme sırasında:
finish() sırasında (kullanıcı “Geri” düğmesine bastı):
Bu nedenle, onDestroy'de viewModelScope'u iptal etmek gerekli değildir — ViewModel bunu kendi başına yapacaktır. lifecycleScope (ViewModel'e değil Activity'ye bağlı) kullanıyorsanız, onDestroy'de lifecycleScope.cancel() ile iptal edin veya Job'u manuel olarak yönetin.
Bir Activity'de doğru lifecycleScope yönetimini gösterir: ağ durumunu izlemek için bir coroutine başlatılır ve onDestroy'de iptal edilir.
class NetworkMonitorActivity : AppCompatActivity() {
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
Log.d("NetworkMonitor", "Ağ kullanılabilir")
}
override fun onLost(network: Network) {
Log.d("NetworkMonitor", "Ağ kayboldu")
}
}
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", "Ağ izleme başlatıldı")
}
}
override fun onDestroy() {
super.onDestroy()
val connectivityManager = getSystemService(ConnectivityManager::class.java)
connectivityManager.unregisterNetworkCallback(networkCallback)
Log.d("NetworkMonitor", "onDestroy: geri çağırma iptal edildi")
}
}
onDestroy'de, ağ geri çağırma kaydı iptal edilir. lifecycleScope, yaşam döngüsü yok edildiğinde otomatik olarak iptal edilir — ayrı bir coroutine iptali gerekmez. Ağ geri çağırması kaydı iptal edilmelidir, aksi takdirde Activity yok edildikten sonra bile sistemde kalır.
Bir Fragment, onDestroyView'de View referanslarını doğru şekilde temizleyerek kapatmalar (closures) nedeniyle bellek sızıntılarını önler.
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 tamamen yok edildi")
}
}
onDestroyView'de, View referansları null olarak ayarlanır — bu, imageLoader'daki bir kapatmanın avatarView'e referans tutması durumunda bellek sızıntısını önler. Fragment'ın kendisi ve ViewModel'i onDestroy'a kadar canlı kalır. imageLoader.cancel(), Fragment ekrandan ayrılırsa yüklemeyi iptal eder.
isFinishing() kullanmak, Activity'nin kullanıcı komutuyla mı yoksa yeniden oluşturma için mi sonlandığını ayırt etmeyi sağlar.
class AnalyticsActivity : AppCompatActivity() {
private val analytics = Analytics()
override fun onDestroy() {
if (isFinishing) {
Log.d("AnalyticsActivity", "Activity finish() ile sonlanıyor — analitik gönderiliyor")
analytics.sendSessionEnd()
} else {
Log.d("AnalyticsActivity", "Activity yeniden oluşturuluyor (döndürme/yapılandırma) — analitik gönderilmiyor")
}
super.onDestroy()
}
}
isFinishing() kontrolü, analitik, günlük kaydı ve oturum verisi temizliği için önemli bir desendir. Döndürme sırasında, oturum sonu olayları gönderilmemelidir — kullanıcı hala uygulama ile çalışmaktadır. Google Analytics'e göre, yanlış isFinishing() kontrolü, %40 oranında yanlış oturum olayının nedenidir.
Sıkça Sorulan Sorular
Evet, çağrılmayabilir — sistem tarafından süreç ölümü, kullanıcı tarafından zorla durdurma veya anormal sonlandırma sırasında. Google'a göre, Activity sonlandırmalarının yaklaşık %5–8'i onDestroy çağrılmadan gerçekleşir. Geliştiriciler kritik verileri kaydetmek için onDestroy'a güvenmemelidir — onPause veya onSaveInstanceState kullanın.
finish() — Activity yok etmeyi başlatan bir çağrıdır. onDestroy — finish() yürütülmesi sırasında çağrılan bir geri çağırmadır. Normal sonlandırmada onDestroy'un çağrılması için finish() gereklidir. finish() sistem veya geliştirici tarafından çağrılabilir, onDestroy yalnızca bir sistem geri çağırmasıdır.
Evet, kesinlikle hem Activity hem de Fragment'da. super.onDestroy(), ChildFragmentManager, LoaderManager ve diğer sistem bileşenlerinin doğru şekilde temizlenmesini sağlar. super.onDestroy() atlanması bellek sızıntılarına ve fragment geri yükleme hatalarına yol açar.
onCleared(), Activity veya Fragment'ın onDestroy'undan sonra çağrılır, ViewModel artık gerekli olmadığında. Ekran döndürme sırasında onCleared() çağrılmaz — ViewModel onDestroy'dan hayatta kalır. Sıra: Activity/Fragment'ın onDestroy'u → (ViewModelStore temizlenir) → onCleared().
Teknik olarak evet, ancak önerilmez. Activity onDestroy'dan hemen sonra yok edilir ve başlatılan Service kontrolsüz kalır. Arka plan görevleri için gecikmeli WorkManager kullanın: WorkManager, Activity sonlandıktan sonra bile yürütmeyi garanti eder ve süreç ölümünden hayatta kalır.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun