DeadObjectException neden ortaya çıkar ve bununla ne yapılmalı

Kerem Aydın·8 Temmuz 2026·⏱3 dk

DeadObjectException, bir istemci süreci veya servisi zaten sonlandırılmış olan uzak bir nesnenin (IBinder) yöntemlerini çağırdığında meydana gelir; bunu düzeltmek için isBinderAlive/pingBinder kontrolü, onServiceDisconnected öğesinin doğru şekilde işlenmesi, yaşam döngüsüne duyarlı bileşenlere geçiş ve yedek mantık ekleme (yeniden bağlanma veya hata toleranslı yol) gereklidir.

DeadObjectException nedir ve tipik senaryolar

DeadObjectException, RemoteException'ın bir alt sınıfıdır: Uzak Binder'ın artık çalışmadığına dair bir sinyal. Sık görülen senaryolar:

  • Bağlı Servis sistem tarafından (düşük bellek nedeniyle) sonlandırıldı ve istemci eski IBinder'ı tutmaya devam etti.
  • Activity/Fragment'in onDestroy() çağrısından sonra yöntemlerin çağrılması.
  • Alıcı tarafın çalışmayı sonlandırdığı AIDL/Messenger üzerinden IPC.
  • Bellek sızıntıları: Statik alanlar veya Handler, IBinder referanslarını tutuyor.

Sorunu nasıl teşhis edilir

  1. Logcat: DeadObjectException filtresi — yığın izini ve çağrı noktasını bulacaksınız.
  2. Binder sızıntılarını tespit etmek için debug modunda StrictMode'u etkinleştirin:
if (BuildConfig.DEBUG) {
  StrictMode.setThreadPolicy(
    StrictMode.ThreadPolicy.Builder()
      .detectAll()
      .penaltyLog()
      .build()
  )
}
  1. ServiceConnection içindeki onServiceDisconnected öğesini kontrol edin — genellikle referansların serbest bırakılması burada unutulur.
  2. Süreç öldürmeyi simüle etme: adb shell am kill veya düşük bellekli testler.

Yığında, servisin sistem tarafından yok edilmesinden hemen sonra istemci tarafında bir çağrı görülüyorsa — IBinder'ın kaydedildiği ve kontrol olmadan yöntemin çağrıldığı yeri arayın.

Pratik çözüm yöntemleri

  1. ServiceConnection içinde işleme:
private var binder: IMyAidlInterface? = null

private val connection = object : ServiceConnection {
  override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
    binder = IMyAidlInterface.Stub.asInterface(service)
  }
  override fun onServiceDisconnected(name: ComponentName?) {
    // servis öldü — referansları temizle ve istekleri durdur
    binder = null
  }
}
  1. Çağırmadan önce durumu kontrol etme:
val b = (binder as? IBinder)
if (b?.isBinderAlive == true) {
  b.pingBinder()
  binder?.someMethod()
} else {
  // yeniden bağlanma veya kullanıcıya hata gösterme
}
  1. Yaşam döngüsüne duyarlı yaklaşımlar:
  • Doğrudan Context referansları tutmamak için arka plan mantığında ViewModel + LiveData/StateFlow kullanın.
  • onStop/onDestroy sırasında servislerden abonelikten çıkın ve kaynakları LifecycleObserver veya ProcessLifecycleOwner aracılığıyla serbest bırakın.
  1. IPC seçimi:
  • Basit görevler için karmaşık AIDL yerine Messenger veya PendingIntent kullanın.
  • Arka plan görevleri için uzun ömürlü servisler yerine WorkManager kullanın.

IBinder veya Context'i statik alanlarda asla saklamayın — bu, sızıntıların ve ardından gelen DeadObjectException'ların sık görülen bir nedenidir.

Yaklaşımların kısa karşılaştırması

YaklaşımZorlukNe zaman uygun
ServiceConnection + onServiceDisconnectedDüşükBağlı servisler
pingBinder/isBinderAliveOrtaServise sık çağrılar
LifecycleObserver / ViewModelDüşükKullanıcı arayüzü ile ilgili bileşenler
AIDL yerine MessengerYüksekBasitleştirilmiş IPC, karmaşık AIDL yokluğu

Sık yapılan hatalar

  • onServiceDisconnected'i görmezden gelmek ve çağrıları sürdürmek.
  • IBinder'ı statik veya uzun ömürlü nesnelerde saklamak.
  • Activity'nin onDestroy() sonrasında servise erişim denemeleri.
  • Servis kullanılamadığında yedek mantığın bulunmaması.

SSS

  • DeadObjectException try/catch ile yakalanmalı mı?
    Evet, kritik noktalarda RemoteException/DeadObjectException yakalayın ve yedek işlemi gerçekleştirin (yeniden bağlanma veya kademeli bozulma).

  • WorkManager'a geçiş yardımcı olur mu?
    Arka plan görevleri için evet. WorkManager, servislerin zorla sonlandırılmasıyla ilgili birçok sorunu ortadan kaldırır.

  • Hata hızlıca nasıl çoğaltılır?
    adb shell am kill veya düşük bellekli cihazda test etme.

Düzeltmelerden sonra hata devam ediyorsa — yığın izini ekleyin ve senaryoyu açıklayın (bağlı servis, AIDL, Activity yaşam döngüsü) — nokta atışı yardımcı olabilirim.