Android'de servisler nasıl çalışır ve nasıl kullanılır

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

Servisler, kullanıcı arayüzü olmadan arka planda çalışan bileşenlerdir: uzun süren görevler için startService/startForegroundService ve doğrudan etkileşim için bindService/ServiceConnection kullanın. Remote Service (AIDL), süreçler arası iletişim (IPC) gerektiğinde uygulanır. Aşağıda hemen uygulayabilmeniz için pratik açıklamalar, kod şablonları ve ipuçları yer almaktadır.

Service nedir ve türleri nelerdir

Service, arka planda iş yapan bir bileşendir: indirmeler, senkronizasyon, ses çalma, ağ olaylarını işleme. Göreve uygun servis türünü seçmek önemlidir:

  • Started Service (startService/startForegroundService ile başlatılır): aktivitelerden bağımsız çalışır. Yaşam döngüsü: onCreate → onStartCommand → onDestroy. Android 8+ üzerinde kararlılık için startForeground() + bildirim kullanın.
  • Bound Service (bindService ile bağlanır): etkileşim için bir arayüz sağlar (genellikle Binder aracılığıyla). Bağlı istemciler olduğu sürece yaşar.
  • Remote Service (ayrı süreç, AIDL): uygulamalar/modüller arasında IPC veya ağır/kritik işlemlerin izolasyonu için kullanılır.

Kısa bir started+bound örneği (Kotlin):

class MyService : Service() {
  private val binder = MyBinder()
  inner class MyBinder : Binder() { fun getService() = this@MyService }
  override fun onBind(intent: Intent?) = binder
  override fun onStartCommand(intent: Intent?, flags: Int, startId: Int) = START_STICKY
}

AndroidManifest içinde kayıt:

<service android:name=".MyService" />

Periyodik görevler için WorkManager tercih edilmelidir (Doze modu ve pil kısıtlamalarını dikkate alır). Service, uzun süreli foreground işlemi veya anında kesintisiz yürütme gerektiğinde kullanılır.

ServiceConnection: doğru şekilde bağlanma ve iletişim kurma

ServiceConnection, istemcinin servis yöntemlerini çağırmak için IBinder aldığı arayüzdür. Yerel bağlama için tipik desen:

private var service: MyService? = null
private val connection = object : ServiceConnection {
  override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
    val myBinder = binder as MyService.MyBinder
    service = myBinder.getService()
  }
  override fun onServiceDisconnected(name: ComponentName?) {
    service = null
  }
}
override fun onStart() {
  bindService(Intent(this, MyService::class.java), connection, Context.BIND_AUTO_CREATE)
}
override fun onStop() {
  unbindService(connection)
}

Pratik öneriler:

  • Bellek sızıntılarını önlemek için unbindService işlemini her zaman onStop/onDestroy içinde yapın.
  • Arayüz basitse, süreçler arası eşzamansız mesajlaşma için AIDL yerine Messenger kullanın.
  • Servis içinde UI iş parçacığını bloklamayın — Coroutine, Executor veya IntentService/JobIntentService kullanın.

Remote Service (AIDL): ne zaman ve nasıl uygulanır

Remote Service, IPC için gereklidir: farklı süreçler, modüler mimari, kritik verilerin korunması. Adımlar:

  1. Bir .aidl dosyası oluşturun (arayüz). IMyService.aidl örneği:
   package com.example;
   interface IMyService {
     String getData();
   }
  1. Sistem Stub/Proxy oluşturur. Serviste Stub'ı uygulayın ve onBind() içinde döndürün:
   private val stub = object : IMyService.Stub() {
     override fun getData(): String = "ok"
   }
   override fun onBind(intent: Intent?) = stub.asBinder()
  1. İstemci, ServiceConnection üzerinden proxy alır ve uzak yöntemleri çağırır.

Remote Service bellek ve pil tüketimini artırır, hata ayıklaması daha zordur ve Parcelable serileştirmesi gerektirir. Yalnızca gerçek IPC ihtiyacı olduğunda kullanın.

Sık yapılan hatalar

  • unbindService çağrılmaması — bellek sızıntıları.
  • Android 8+ üzerinde uzun süreli arka plan görevleri için startForeground() çağrısının unutulması — servis sonlandırılır.
  • Basit mesajlar için AIDL kullanılması — aşırı yük. Messenger veya BroadcastReceiver seçin.
  • İzinlerin (BIND_SERVICE) ve intent-filter güvenliğinin göz ardı edilmesi.
  • Servis yöntemlerinde ana iş parçacığının bloklanması.

SSS

  • startService ile bindService arasında ne zaman seçim yapılmalı?
    • startService — görevin kullanıcı arayüzünden bağımsız olarak yürütülmesi gerekiyorsa. bindService — servisin yöntemlerine doğrudan erişim gerekiyorsa.
  • Servis nasıl doğru şekilde durdurulur?
    • Started servis için: stopSelf() veya stopService(intent). Bound servis için — unbindService; başka istemci yoksa ve servis başlatılmamışsa sonlanır.
  • Pil optimizasyonu sırasında davranış nasıl test edilir?
    • Gerçek cihazlarda pil optimizasyonu açıkken ve Doze modunda test edin; Doze'u simüle etmek için adb kullanın.
  • Servisten kullanıcı arayüzüne erişilebilir mi?
    • Hayır. Servis arka plan iş parçacığında çalışır — Broadcast/Handler/LiveData aracılığıyla etkileşim kurun veya intent/bildirim gönderin.

İsterseniz, Service + Foreground Notification için kompakt bir şablon veya Parcelable içeren bir AIDL örneği hazırlayabilirim.