Context, Application ve Service arasındaki farklar ve ne zaman hangisinin kullanılacağı
Kısa cevap: Kullanıcı arayüzü (UI) ve pencere/tema ile ilgili her şey için Activity/Fragment context'ini; uzun ömürlü singleton'lar ve sistem API'leri için applicationContext'i; ekran kapandıktan sonra çalışması gereken görevler için Service'i (genellikle foreground) kullanın, ancak önce WorkManager'ı değerlendirin.
Context — Nedir ve Nasıl Seçilir?
Context; kaynaklara ve sistem servislerine erişim sağlayan bir arayüzdür: kaynaklar, dosyalar, getSystemService(), bileşen başlatma. Android'de bunu Activity, Service ve Application sınıfları ile ayrıca wrapper'lar (ContextWrapper) uygular.
Pratik kurallar:
- UI (diyaloglar, temalar, navigasyon) — Activity/Fragment context'i:
this,requireContext(),requireActivity(). - Uzun ömürlü nesneler (repository'ler, önbellekler, veritabanı) —
applicationContext. - View kendi
context'ini alır, ancak Activity'yi statik alanlarda saklamayın.
Yanlış Context seçimi, bellek sızıntılarının ve WindowManager$BadTokenException istisnalarının yaygın nedenidir.
Application — Global Başlatma
Application, süreç başlatıldığında bir kez oluşturulur ve sonlanana kadar yaşar. Bu, UI içermeyen bir Context'tir ve tüm süreç boyunca yaşaması gereken bileşenlerin başlatılması ve saklanması için uygundur.
Ne zaman kullanılır:
- DI (Bağımlılık Enjeksiyonu), loglama, veritabanlarının başlatılması.
- Singleton'lara
applicationContextaktarma. - Önbelleklerin ve global yöneticilerin saklanması.
Örnek (Kotlin):
class App : Application() {
override fun onCreate() {
super.onCreate()
initDI()
initLogger()
}
}
Ne zaman kullanılmaz:
- Diyalog oluşturma, PopupMenu, temalar için — Activity context'i gerekir.
- Pencere/tema ile bağlantılı işlemler için
applicationContextkullanmayın.
Diyalog oluşturma veya navigasyon için adapter'lara applicationContext aktarmayın; bu hatalara ve kötü kullanıcı deneyimine (UX) yol açar.
Service — Gerçek Arka Plan Görevleri İçin (ve Alternatifler)
Service, UI içermeyen bir bileşendir ve Context'i uygular, ancak varsayılan olarak UI thread'inde çalışır. Service'i, Activity kapatıldıktan sonra görevin devam etmesi gerektiğinde (müzik, konum takibi) kullanın. Kısa veya ertelenmiş görevler için genellikle WorkManager veya ViewModel içindeki coroutine daha uygundur.
Temel noktalar:
- Service yeni bir thread oluşturmaz; işi coroutine/thread'e taşımanız gerekir.
- Kullanıcıya görünürlük gerektiren uzun süreli görevler için bildirimli foreground service kullanın.
- Ertelenmiş/periyodik çalışmalar için WorkManager'ı tercih edin (Doze kısıtlamalarını dikkate alarak).
Başlangıç Service örneği:
class MyService : Service() {
override fun onBind(intent: Intent?) = null
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
CoroutineScope(Dispatchers.Default).launch { doWork() }
return START_STICKY
}
}
Yaygın Hatalar
- Activity/Fragment'ın singleton'larda saklanması -> bellek sızıntıları.
- UI işlemleri için
applicationContextkullanılması -> BadTokenException/yanlış tema. - Kısa arka plan operasyonları için WorkManager yerine Service başlatılması -> gereksiz pil tüketimi.
- Service'in ayrı bir thread'de çalıştığının varsayılması.
SSS
- Service yerine her zaman WorkManager kullanmak gerekir mi?
- Hayır. Görünür bildirim/ses/konum takibi ile ilgili uzun süreli görevler için Service (foreground) daha iyidir. Ertelenmiş/periyodik çalışmalar için — WorkManager.
- Veritabanı örneğini Application'da saklayabilir miyim?
- Evet. Application'da başlatın ve oluşturma sırasında
applicationContextkullanın.
- Evet. Application'da başlatın ve oluşturma sırasında
- Context'i kütüphanelere aktarırken bellek sızıntısını nasıl önlerim?
- Uzun ömürlü nesneler için
applicationContextaktarın; UI için Activity/Fragment aktarın ve bunları static olarak kaydetmeyin.
- Uzun ömürlü nesneler için
İyi bir pratik kural: Ekranı aşabilecek her şeyi applicationContext'e bağlayın; pencere, tema ve yaşam döngüsü ile ilgili her şeyi Activity/Fragment'a bağlayın; görev UI olmadan çalışacaksa Service'i düşünün, ancak önce WorkManager'ı kontrol edin.