Hizmetlere genel bakış

Service, gerçekleştirebilen uygulama bileşeni arka planda uzun süreli işlemler yapmanıza olanak tanır. Kullanıcı arayüzü sağlamaz. Bir kez başlatıldığında, kullanıcı başka bir hizmete geçse bile bir hizmet bir süre daha çalışmaya devam edebilir. bir uygulamadır. Bileşenler, aynı zamanda bir hizmetle etkileşim kurmak ve hatta işlemler arası iletişim (IPC) Örneğin, bir hizmet; ağ işlemlerini gerçekleştirebilir, müzik çalma, dosya I/O performansı gösterme veya bir içerik sağlayıcıyla etkileşim kurma.

Dikkat: Bir hizmet, barındırıldığı ana iş parçacığında çalışıyor işlem; hizmet kendi ileti dizisini oluşturmaz ve oluşturmaz siz aksini belirtmedikçe ayrı bir işlemde çalıştırılır. Tüm engelleme işlemlerini Uygulamadan kaçınmak için hizmet içinde ayrı bir iş parçacığı Yanıt Vermiyor (ANR) hataları.

Hizmet Türleri

Üç farklı hizmet türü vardır:

Ön plan

Bir ön plan hizmeti, belirtir. Örneğin, bir ses uygulaması ses çalmak için bir ön plan hizmeti kullanır ses parçası. Ön plan hizmetleri bir Bildirim görüntülemelidir. Ön plan hizmetleri kullanıcı etkileşim kurmasa bile çalışmaya devam eder inceleyebilirsiniz.

Bir ön plan hizmeti kullanırken bir ön plan hizmeti kullandığınızda Kullanıcılar hizmetin çalıştığının farkındadır. Bu bildirim, hizmet durdurulmazsa veya ön plan.

Yapılandırma hakkında daha fazla bilgi ön plan hizmetlerini uygulamasını indirin.

Not: WorkManager API, görevleri planlamak için esnek bir yol sunar ve çalışabilmek bu işleri ön plan hizmetleri olarak devredebilirsiniz. Birçok durumda, WorkManager, doğrudan ön plan hizmetlerinin kullanılması tercih edilir.

Arka plan
Bir arka plan hizmeti, Google tarafından doğrudan fark edilmeyen bir işlemi gerçekleştirir gösterir. Örneğin, bir uygulama depolama alanını daraltmak için bir hizmet kullandıysa bu genellikle bir arka plan hizmeti olur.

Not: Uygulamanız API düzeyi 26 veya üstünü hedefliyorsa sistem, arka planda çalıştırma kısıtlamaları uygular hizmetlerini kullanmalarına olanak tanır. Çoğu zaman bazı durumlarda, konum bilgilerine arka plan. Bunun yerine görevleri planlarken WorkManager içinde).

Bağlı
Bir uygulama bileşeni, bindService() yöntemini çağırarak hizmete bağlandığında hizmet bağlıdır. Bağlı hizmet bir istemci-sunucu bileşenlerin hizmetle etkileşim kurmasına, istek göndermesine, sonuçları almasına, bunu süreçler arası iletişim (IPC) olan süreçlerde bile yapabilirsiniz. Bağlı bir hizmet yalnızca çalışır devam ettirebilirsiniz. Birden fazla bileşen aynı anda çalışır ancak tüm öğelerin bağlantısı kaldırıldığında hizmet kaldırılır.

Bu dokümanda genellikle başlatılan ve bağlı hizmetler ayrı ayrı tartışılsa da hizmetiniz her iki şekilde de çalışabilir; başlatılabilir (sürekli olarak çalışacak) ve bağlama'yı tıklayın. Bu, birkaç geri çağırma yöntemi uygulayıp uygulamamanızla ilgilidir: Bileşenlerin başlatmasına izin vermek için onStartCommand() ve bağlamaya izin vermek için onBind().

Hizmetinizin başlatılmış, bağlı veya her iki durumda da uygulama bileşenleri hizmeti, herhangi bir bileşenin kullandığı şekilde kullanabilir (ayrı bir uygulamadan olsa bile), bir etkinlik (Intent ile başlatarak) Ancak, feed'inizde söz konusu hizmeti manifest dosyasında gizli olarak işaretleyebilir ve diğer uygulamalardan erişimi engelleyebilirsiniz. Bu konu, manifesto içinde yeniden etkinleştirilmelidir.

Hizmet ve iş parçacığı arasında seçim yapma

Hizmet, kullanıcı sade bir şekilde çalışmasa bile arka planda çalışabilen bir bileşendir. uygulamanızla etkileşimde bulunursa bu nedenle hizmet oluşturmalısınız. gerekiyor.

Ana iş parçacığınızın dışında ancak yalnızca kullanıcı etkileşimde bulunurken çalışma yapmanız gerekiyorsa bir iş parçacığı yerine başka bir uygulama bağlamında bir bileşenidir. Örneğin, müzik çalmak isterseniz yalnızca etkinliğiniz devam ederken onCreate() üzerinde bir ileti dizisi oluşturabilirsiniz. onStart() içinde çalıştırmaya başlarsanız, onStop() içinde durduracağım. java.util.concurrent paketindeki iş parçacığı havuzları ve yürütücüler de kullanılabilir. veya Kotlin eş yordamları Thread sınıf. Bkz. hakkında daha fazla bilgi için Android'de ileti dizisi dokümanı arka plandaki iş parçacıklarına taşıma.

Kullandığınız bir hizmetin, uygulamanızın ana iş parçacığında Bu nedenle, iş yükü yoğun bir şekilde değiştiriliyorsa veya engelleme işlemleri.

Temel bilgiler

Hizmet oluşturmak için bir Service alt sınıfı oluşturmanız veya birini kullanmanız gerekir alt sınıflarından birini seçin. Uygulamanızda, aynı özelliklere sahip olan bazı geri çağırma yöntemlerini hizmet yaşam döngüsünün temel unsurlarını ele alma ve bileşenlerin hızlı bir şekilde ve uygunsa hizmete bağlanmasını sağlamak. Bunlar, doğru bir teklif verme stratejisi için geçersiz kılma:

onStartCommand()
Başka bir bileşen (etkinlik gibi) hizmetin başlatılmasını istediğinde sistem, startService() yöntemini çağırarak bu yöntemi çağırır. Bu yöntem yürütüldüğünde hizmet başlatılır ve süresiz olarak arka planda çalışmasını sağlar. Bunu uygularsanız hizmeti devre dışı bırakmak sizin sorumluluğunuzdadır işlemi stopSelf() veya stopService() numaralı telefonu arayarak tamamlanır. Yalnızca bağlama sağlamak istiyorsanız bu yöntemi uygulamanız gerekir.
onBind()
Başka bir bileşen hizmete bağlanmak (ör. RPC gerçekleştirmek) istediğinde sistem bindService() yöntemini çağırarak bu yöntemi çağırır. Bu yöntemi uygularken müşterilerin döndürerek bir IBinder döndürerek hizmetle iletişim kurmak için kullanın. Her zaman bu yöntemi uygulamalısınız. Ancak, bağlamaya izin vermek istemiyorsanız null.
onCreate()
Hizmet şu durumlarda tek seferlik kurulum prosedürlerini gerçekleştirmek için sistem bu yöntemi çağırır: başlangıçta oluşturulur ( onStartCommand() veya onBind()). Hizmet zaten çalışıyorsa bu yöntem çağrıldı.
onDestroy()
Hizmet artık kullanılmadığında ve kaldırılırken sistem bu yöntemi çağırır. Hizmetiniz, ileti dizileri, kayıtlı iletiler gibi kaynakları temizlemek için bunu uygulamalıdır. genel bir bilgidir. Bu, hizmetin aldığı son çağrıdır.

Bir bileşen, hizmeti startService() çağırarak başlatırsa (bu durumda onStartCommand() çağrısına neden olur), hizmet stopSelf() veya başka bir kodla kendiliğinden durana kadar çalışmaya devam eder bileşeni, stopService() yöntemini çağırarak bunu durdurur.

Bir bileşen, Hizmeti oluşturmak için bindService() kullanılır ve onStartCommand() çağrılmaz; hizmet çalıştırılır. bileşen kendisine bağlı olduğu sürece geçerlidir. Hizmetin tüm istemcileriyle bağlantısı kaldırıldıktan sonra, sistem onu yok eder.

Android sistemi, bir hizmeti yalnızca bellek az olduğunda durdurur ve sistemi kurtarması gerekir. için en az bir kaynak bulunur. Hizmet, kullanıcı erişimi olan bir etkinliğe bağlıysa ölülme ihtimali azalır. Hizmetin ön planda çalışacağı belirtildiyse hizmet nadiren sonlandırılır. Hizmet başlatıldı ve uzun süre çalışıyorsa sistem konumunu düşürür. zamanla arka plan görevleri listesinde yer almaya başlar ve hizmet, diğer web sitesi hizmetiniz başlarsa yeniden başlatma işlemlerini sorunsuz bir şekilde halledecek şekilde tasarlamanız gerekir. sistem tarafından belirlenir. Hizmetiniz sistem tarafından sonlandırılırsa kaynaklar uygun hale gelir gelmez yeniden başlatılır kullanılabilir ancak bu aynı zamanda onStartCommand() öğesinden döndürdüğünüz değere bağlıdır. Okuyucu Gelirleri Yöneticisi'ni hakkında bilgi için İşlemler ve İleti Dizisi bölümüne bakın uygulayacaksınız.

İlerleyen bölümlerde, Google Etiket Yöneticisi'ni kullanarak startService() ve bindService() hizmet yöntemleri ve bunları diğer uygulama bileşenlerinden alır.

Manifest dosyasında hizmet tanımlama

Uygulamanızda tüm hizmetleri manifest dosyanızda olduğu gibi, etkinlikler ve diğer bileşenlerde yaptığınız gibi çalışır.

Hizmetinizi beyan etmek için <service> öğesi ekleyin <application> için bir alt öğe olarak öğesine dokunun. Örnek:

<manifest ... >
  ...
  <application ... >
      <service android:name=".ExampleService" />
      ...
  </application>
</manifest>

<service> öğesini inceleyin hizmetinizi manifest dosyasında beyan etme hakkında daha fazla bilgi edinmek için bu makaleye bakın.

Aşağıdaki işlemler için <service> öğesine ekleyebileceğiniz başka özellikler de vardır: hizmeti başlatmak için gerekli izinler ve süreci otomatik olarak başlatmak için gereken izinler hizmetin çalışması gerekir. android:name özelliği, gerekli tek özelliktir. Hizmetin sınıf adını belirtir. Şu tarihten sonra: uygulamanızı yayınlarsanız bozulma riskini önlemek için bu adı değiştirmeyin. açık amaçlara bağlı olduğundan emin olun (bunlar, Things'i yönetmek için Bu Değişmez) oturum açın.

Dikkat: Uygulamanızın güvenli olduğundan emin olmak için her zaman bir Service başlatırken amacı açıkça belirtin ve şunun için intent filtreleri bildirmeyin: nasıl sağlayabileceğini de öğreneceksiniz. Bir hizmeti başlatmak için örtülü niyet kullanmak güvenlik tehlikesi teşkil eder. amaca yanıt veren hizmetten emin olması ve kullanıcının hangi hizmetin başlar. Android 5.0 (API düzeyi 21) sürümünden itibaren, Dolaylı bir niyetle bindService().

Hizmetinizin yalnızca uygulamanızın kullanımına sunulduğundan emin olmak için android:exported dahil özelliğini kullanarak false olarak ayarlayın. Böylece diğer uygulamaların kullanıma sunulmasını isteyebilir.

Not: Kullanıcılar, cihazlarında hangi hizmetlerin çalıştığını görebilir. Herhangi bir tanımadıkları veya güvenmedikleri bir hizmeti devre dışı bırakabilirler. İçinde hizmetinizin kullanıcılar tarafından yanlışlıkla durdurulmasını önlemek amacıyla eklemek için android:description özelliğini <service> öğesine dokunun. Açıklamada hizmetin ne yaptığını ve ne gibi faydaları olduğunu açıklayan kısa bir cümle yazın yardımcı olur.

Başlatılmış bir hizmet oluşturma

Başlatılan bir hizmet, başka bir bileşenin startService() yöntemini çağırarak başladığı ve sonrasında hizmetin onStartCommand() yöntemini çağırın.

Bir hizmet başlatıldığında, o hizmetin bileşeni görebilirsiniz. Hizmet, arka planda süresiz olarak çalışabilir ancak başlatan bileşen kaldırılır. Bu nedenle, işi zamanında tamamlamak için hizmet stopSelf() çağrısıyla tamamlanır. Aksi takdirde başka bir bileşen stopService() numaralı telefonu arayarak bunu durdurun.

Etkinlik gibi bir uygulama bileşeni, startService() çağrısı yapıp bir Intent ileterek hizmeti başlatabilir hizmeti belirten ve hizmetin kullanması için gerekli tüm verileri içeren bir etikettir. Hizmetin onStartCommand() yöntemindeki bu Intent.

Örneğin, bir etkinliğin bazı verileri çevrimiçi bir veritabanına kaydetmesi gerektiğini varsayalım. Etkinlik bir tamamlayıcı hizmet başlatabilir ve startService() öğesine bir intent ileterek tasarruf edilecek verileri bu hizmete gönderebilir. Hizmet onStartCommand() ürününde isteği alır, internete bağlanır ve aşağıdaki işlemleri gerçekleştirir: devam eder. İşlem tamamlandığında hizmet kendini durdurur ve yok.

Dikkat: Bir hizmet, uygulama ile aynı işlemde çalışır burada tanımlandığı şekilde ve varsayılan olarak söz konusu uygulamanın ana iş parçacığında. Aldığınız hizmet Kullanıcı aynı kaynaktan bir etkinlikle etkileşimde bulunurken yoğun veya engelleme işlemleri gerçekleştirir. hizmet, etkinlik performansını yavaşlatır. Uygulamanın etkilenmesini önlemek için hizmet içinde yeni bir iş parçacığı başlatın.

Service sınıfı temeldir. bir sınıfa sahip olur. Bu sınıfın kapsamını genişlettiğinizde, hizmet tüm çalışmalarını tamamlayabiliyor; hizmet, uygulamanızın ana iş parçacığını ve uygulamanızın çalışmakta olduğu tüm etkinliklerin performansını yavaşlatabilir.

Android çerçevesi ayrıca IntentService sağlar kullanan Service alt sınıfı tüm başlangıç isteklerini teker teker işlemek için çalışan iş parçacığı. Bu sınıfı kullanmak önerilir. Bunun nedeni, Arka planda yürütme sınırları kullanıma sunuldu. Ayrıca, Android 11'den itibaren desteği sonlandırıldı. jobIntentService'i bir CSV dosyasında Android'in yeni sürümleriyle uyumlu IntentService yerine yeni bir uygulama paketi göreceksiniz.

Aşağıdaki bölümlerde kendi özel hizmetinizi nasıl uygulayabileceğiniz açıklanmıştır, ancak çoğu kullanım alanında WorkManager'ı kullanmanız kesinlikle önerilir. Android'de arka plan işleme kılavuzuna bakın ihtiyaçlarınıza uygun bir çözüm olup olmadığına bakabilirsiniz.

Hizmet sınıfını genişletme

Service sınıfını uzatabilirsiniz kullanabilirsiniz. Temel bir uygulama aşağıdaki gibi görünebilir:

Kotlin

class HelloService : Service() {

    private var serviceLooper: Looper? = null
    private var serviceHandler: ServiceHandler? = null

    // Handler that receives messages from the thread
    private inner class ServiceHandler(looper: Looper) : Handler(looper) {

        override fun handleMessage(msg: Message) {
            // Normally we would do some work here, like download a file.
            // For our sample, we just sleep for 5 seconds.
            try {
                Thread.sleep(5000)
            } catch (e: InterruptedException) {
                // Restore interrupt status.
                Thread.currentThread().interrupt()
            }

            // Stop the service using the startId, so that we don't stop
            // the service in the middle of handling another job
            stopSelf(msg.arg1)
        }
    }

    override fun onCreate() {
        // Start up the thread running the service.  Note that we create a
        // separate thread because the service normally runs in the process's
        // main thread, which we don't want to block.  We also make it
        // background priority so CPU-intensive work will not disrupt our UI.
        HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND).apply {
            start()

            // Get the HandlerThread's Looper and use it for our Handler
            serviceLooper = looper
            serviceHandler = ServiceHandler(looper)
        }
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show()

        // For each start request, send a message to start a job and deliver the
        // start ID so we know which request we're stopping when we finish the job
        serviceHandler?.obtainMessage()?.also { msg ->
            msg.arg1 = startId
            serviceHandler?.sendMessage(msg)
        }

        // If we get killed, after returning from here, restart
        return START_STICKY
    }

    override fun onBind(intent: Intent): IBinder? {
        // We don't provide binding, so return null
        return null
    }

    override fun onDestroy() {
        Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show()
    }
}

Java

public class HelloService extends Service {
  private Looper serviceLooper;
  private ServiceHandler serviceHandler;

  // Handler that receives messages from the thread
  private final class ServiceHandler extends Handler {
      public ServiceHandler(Looper looper) {
          super(looper);
      }
      @Override
      public void handleMessage(Message msg) {
          // Normally we would do some work here, like download a file.
          // For our sample, we just sleep for 5 seconds.
          try {
              Thread.sleep(5000);
          } catch (InterruptedException e) {
              // Restore interrupt status.
              Thread.currentThread().interrupt();
          }
          // Stop the service using the startId, so that we don't stop
          // the service in the middle of handling another job
          stopSelf(msg.arg1);
      }
  }

  @Override
  public void onCreate() {
    // Start up the thread running the service. Note that we create a
    // separate thread because the service normally runs in the process's
    // main thread, which we don't want to block. We also make it
    // background priority so CPU-intensive work doesn't disrupt our UI.
    HandlerThread thread = new HandlerThread("ServiceStartArguments",
            Process.THREAD_PRIORITY_BACKGROUND);
    thread.start();

    // Get the HandlerThread's Looper and use it for our Handler
    serviceLooper = thread.getLooper();
    serviceHandler = new ServiceHandler(serviceLooper);
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
      Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();

      // For each start request, send a message to start a job and deliver the
      // start ID so we know which request we're stopping when we finish the job
      Message msg = serviceHandler.obtainMessage();
      msg.arg1 = startId;
      serviceHandler.sendMessage(msg);

      // If we get killed, after returning from here, restart
      return START_STICKY;
  }

  @Override
  public IBinder onBind(Intent intent) {
      // We don't provide binding, so return null
      return null;
  }

  @Override
  public void onDestroy() {
    Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
  }
}

Örnek kod, onStartCommand() içindeki tüm gelen aramaları işler ve çalışmayı arka plandaki bir ileti dizisinde çalışan bir Handler üzerinde yayınlar. IntentService ile aynı şekilde çalışır ve tüm istekleri sırayla, arka arkaya işler. Kodu, işi bir iş parçacığı havuzunda çalıştıracak şekilde değiştirebilirsiniz (örneğin, aynı anda birden fazla istek çalıştırmak istiyorsanız).

onStartCommand() yönteminin Tam sayı. Tam sayı, sistemin etkinliği sona erdirir. Döndürülen değer onStartCommand() değeri şunlardan biri olmalıdır: sabit değerler:

START_NOT_STICKY
onStartCommand() iade edildikten sonra sistem hizmeti sonlandırırsa beklemede olmadığı sürece hizmeti yeniden oluşturmayın daha fazla bilgi edineceksiniz. Bu, gerekli olmadığında hizmetinizi çalıştırmaktan kaçınmak için en güvenli seçenektir ve uygulamanızın tamamlanmamış işleri yeniden başlatabileceği durumlar.
START_STICKY
onStartCommand() geri geldikten sonra sistem hizmeti kaldırırsa hizmeti yeniden oluşturup onStartCommand() yöntemini çağırın ancak son amacı yeniden teslim etmeyin. Bunun yerine, sistem onStartCommand() öğesini bir hizmeti başlatmak için bekleyen niyet yoksa null intent. Böyle bir durumda, bu amaçların teslim edildiği anlamına gelir. Bu, cihazınızda bulunmayan medya oynatıcılar (veya benzer hizmetler) için komutlar yürütüyorsa ancak süresiz olarak çalışıyor ve bir iş bekliyor.
START_REDELIVER_INTENT
onStartCommand() geri döndükten sonra sistem hizmeti kapatırsa hizmeti yeniden oluşturun ve onStartCommand() hedefine teslim edilen son amaca göre onStartCommand() çağrısı yapın geliştirmenizi sağlar. Beklemedeki tüm amaçlar da sırayla teslim edilir. Bu, şu hizmetler için uygundur: hemen devam ettirilmesi gereken bir işi (ör. dosya indirme) aktif olarak icra eden bir fonksiyondur.

Bu döndürülen değerler hakkında daha fazla bilgi için bağlı referansa bakın belgelerini inceleyin.

Hizmet başlatma

Bir etkinlikten veya başka bir uygulama bileşeninden hizmeti başlatmak için Intent geçiliyor startService() veya startForegroundService(). İlgili içeriği oluşturmak için kullanılan Android sistemi, hizmetin onStartCommand() yöntemini çağırır ve bunu Intent iletir. Bu kod, hangi hizmetin başlatılacağını belirtir.

Not: Uygulamanız API düzeyi 26 veya üstünü hedefliyorsa sistem arka plan hizmetlerinin kullanımına veya oluşturulmasına kısıtlamalar getirir. ön planda olmasını sağlar. Bir uygulamanın ön plan hizmeti oluşturması gerekiyorsa Uygulama, startForegroundService() numarasını çağırmalıdır. Bu yöntem bir arka plan hizmeti oluşturur ancak yöntemi, hizmetin kendisini tanıtacağını ve ön plan. Hizmet oluşturulduktan sonra startForeground() yöntem dahilinde beş saniye.

Örneğin, bir etkinlik, aşağıda gösterildiği gibi önceki bölümde (HelloService) startService() ile açık bir amaç kullanarak örnek hizmeti başlatabilir:

Kotlin

startService(Intent(this, HelloService::class.java))

Java

startService(new Intent(this, HelloService.class));

startService() yöntemi hemen geri döner ve Android sistemi, hizmetin onStartCommand() yöntemini çağırır. Hizmet çalışmıyorsa sistem önce onCreate() yöntemini, ardından çağrıyı onStartCommand().

Hizmet aynı zamanda bağlama da sunmuyorsa startService() ile sağlanan intent, uygulama bileşeni ve hizmet. Ancak hizmetin bir sonucu geri göndermesini istiyorsanız hizmeti başlatan istemci bir yayın için PendingIntent oluşturabilir (getBroadcast() ile) ve hizmete teslim ederek hizmeti başlatan Intent. Hizmet, daha sonra yayını kullanabilirsiniz.

Hizmeti başlatmaya yönelik birden fazla istek, hizmetin onStartCommand() Ancak, yalnızca bir kez durdurma isteği hizmeti (stopSelf() veya stopService() ile) durdurması gerekir.

Bir hizmeti durdurma

Başlatılan bir hizmet kendi yaşam döngüsünü yönetmelidir. Yani, sistem bir şeyi sistem belleğini ve hizmeti kurtarması gerekmiyorsa hizmeti yok eder onStartCommand() değeri döndürüldükten sonra çalışmaya devam eder. İlgili içeriği oluşturmak için kullanılan hizmet stopSelf() veya başka bir telefon numarasını arayarak kendi kendine durmalıdır bileşeni, stopService() çağrısı yaparak bunu durdurabilir.

stopSelf() veya stopService() ile durdurulması istendiğinde sistem, hizmeti derhal kaldırır yapmasını sağlar.

Hizmetiniz aynı anda onStartCommand() için birden fazla istek işliyorsa yeni bir hizmet başlatmış olabileceğinizden, bir başlatma isteğini işlemeyi İsteği başlatma (ilk isteğin sonunda durdurulması ikinci isteği de sonlandırır). Kaçınılması gerekenler aşağıdaki durumlardan emin olmak için stopSelf(int) kullanabilirsiniz: her zaman en son başlatma isteğine dayanması gerekir. Yani stopSelf(int) işlevini çağırdığınızda başlangıç isteğinin kimliğini (startId onStartCommand() adresine teslim edilir) karşılık gelir. Ardından hizmet, stopSelf(int) öğesini çağırabilmeniz için yeni bir başlatma isteği alırsa kimlik eşleşmez ve hizmet durmaz.

Dikkat: Sistem kaynaklarını boşa harcamak ve varsa, çalışması bittiğinde uygulamanızın hizmetlerini durdurduğundan emin olun. Gerektiğinde diğer bileşenler stopService() kodunu çağırarak hizmeti durdurabilir. Hizmet için bağlamayı etkinleştirseniz bile onStartCommand() numaralı telefona bir çağrı alırsa hizmeti her zaman kendiniz durdurmanız gerekir.

Bir hizmetin yaşam döngüsü hakkında daha fazla bilgi edinmek için aşağıdaki Hizmetin Yaşam Döngüsünü Yönetme bölümüne göz atın.

Bağlı hizmet oluşturma

Bağlı hizmet, uzun süreli bağlantı oluşturmak için bindService() çağrısı yaparak uygulama bileşenlerinin bu hizmete bağlanmasını sağlayan bir hizmettir. Genellikle bileşenlerin startService() çağrısı yaparak onu başlatmasına izin vermez.

Etkinliklerden hizmetle etkileşim kurmak istediğinizde bağlı bir hizmet oluşturun veya uygulamanızın bazı işlevlerini kullanıcıların uygulamanızı diğer uygulamalarda ise işlemler arası iletişim (IPC) kullanılır.

Bağlı hizmet oluşturmak için onBind() geri çağırma yöntemini uygulayarak şu değeri döndüren bir IBinder: hizmetle iletişimin arayüzünü tanımlar. Diğer uygulama bileşenleri Arayüzü almak için bindService() hizmette yöntemleri çağırmaya başlar. Hizmet yalnızca Google'ın değil, aynı zamanda bağlı olduğundan, hizmete bağlı bileşen olmadığında sistem onu yok eder. Bağlı bir hizmeti, hizmet sunulduğunda olduğu gibi durdurmanız gerekmez. onStartCommand() tarihine kadar başladı.

Bağlı hizmet oluşturmak için bir istemcinin nasıl bağlanacağını ve sağlamak için çok iyidir. Hizmet ile veri arasındaki bu arayüz İstemci de IBinder uygulaması olmalıdır ve hizmetiniz için onBind() geri çağırma yönteminden döndürülür. Müşteri IBinder talimatını aldıktan sonra işlem başlayabilir. bu arayüzden hizmetle etkileşimde bulunmanızı sağlar.

Birden çok istemci, hizmete aynı anda bağlanabilir. Bir müşteri hizmet, bağlantıyı kesmek için unbindService() öğesini çağırır. Hizmete bağlı istemci olmadığında sistem, hizmeti kaldırır.

Bağlı bir hizmeti uygulamanın birden çok yolu vardır ve bu yöntem, daha karmaşıktır. Bu nedenlerle, bağlı hizmet açıklaması bağlı hizmetler hakkında ayrı bir doküman hazırlayacağız.

Kullanıcıya bildirim gönderme

Bir hizmet çalışırken snackbar bildirimlerini veya durum çubuğu bildirimlerini kullanarak etkinlikler hakkında kullanıcıyı bilgilendirebilir.

Snackbar bildirimi, geçerli pencerenin yüzeyinde yalnızca bir kaybolmadan önce zaman geçiriyorlar. Bir durum çubuğu bildirimi, durum çubuğunda mesajı gösterilir. Kullanıcının bir işlem yapmak (örneğin, etkinlik başlatmak) için seçebileceği mesaj.

Genellikle durum çubuğu bildirimi, şu gibi bir arka plan çalışmasında kullanılacak en iyi tekniktir: bir dosya indirme işlemi tamamlandıysa kullanıcı artık dosya üzerinde işlem yapabilir. Kullanıcı bildirimi genişletilmiş görünümden seçtiğinde, bildirim bir etkinlik başlatabilir (indirilen dosyayı görüntülemek için gibi).

Bir hizmetin yaşam döngüsünü yönetme

Bir hizmetin yaşam döngüsü, bir etkinliğin yaşam döngüsünden çok daha basittir. Ancak aslında bu, hizmetinizin nasıl oluşturulduğuna ve yok edildiğine çok dikkat etmeniz önemlidir. arka planda çalışabileceğinden emin olun.

Hizmetin yaşam döngüsü (oluşturulduğundan kaldırılmasına kadar) şu iki yoldan birini tercih edebilirsiniz:

  • Başlatılan bir hizmet

    Hizmet, başka bir bileşen startService() yöntemini çağırdığında oluşturulur. Daha sonra hizmet süresiz olarak çalışır stopSelf() numaralı telefonu arayarak durdurabilir. Başka bir bileşen de stopService() numaralı telefonu arayın. Hizmet durdurulduğunda, sistem hizmeti kaldırır.

  • Bağlı hizmet

    Hizmet, başka bir bileşen (istemci) bindService() çağırdığında oluşturulur. Ardından istemci, bu hizmetle IBinder arayüzü üzerinden. İstemci, şu numarayı arayarak bağlantıyı kapatabilir: unbindService() Birden çok müşteri ve hepsinin bağlantısı kaldırıldığında sistem hizmeti kaldırır. Hizmet kendini durdurması gerekmez.

Bu iki yol tamamen ayrı değildir. Şu anda oturum açmış olduğunuz startService() ile başladı. Örneğin, şunları yapabilirsiniz: çalacak müziği tanımlayan bir Intent ile startService() çağırarak arka plan müzik hizmeti başlatın. Daha sonra, Kullanıcı oyuncu üzerinde kontrol sahibi olmak veya oynatıcı hakkında bilgi almak istediğinde şarkı çalmaya başladığında, bir etkinlik bindService() numaralı telefonu arayarak hizmete bağlanabilir. Bu gibi durumlarda, tüm istemcilerin bağlantısı kaldırılana kadar stopService() veya stopSelf() hizmeti durdurmaz.

Yaşam döngüsü geri çağırmalarını uygulama

Etkinliklerde olduğu gibi, bir hizmetin de yaşam döngüsü geri çağırma yöntemlerini uygulayarak değişiklikleri yapabilir ve işleri uygun zamanlarda gerçekleştirebilirsiniz. Aşağıdaki iskelet hizmet yaşam döngüsü yöntemlerinin her birini gösterir:

Kotlin

class ExampleService : Service() {
    private var startMode: Int = 0             // indicates how to behave if the service is killed
    private var binder: IBinder? = null        // interface for clients that bind
    private var allowRebind: Boolean = false   // indicates whether onRebind should be used

    override fun onCreate() {
        // The service is being created
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // The service is starting, due to a call to startService()
        return startMode
    }

    override fun onBind(intent: Intent): IBinder? {
        // A client is binding to the service with bindService()
        return binder
    }

    override fun onUnbind(intent: Intent): Boolean {
        // All clients have unbound with unbindService()
        return allowRebind
    }

    override fun onRebind(intent: Intent) {
        // A client is binding to the service with bindService(),
        // after onUnbind() has already been called
    }

    override fun onDestroy() {
        // The service is no longer used and is being destroyed
    }
}

Java

public class ExampleService extends Service {
    int startMode;       // indicates how to behave if the service is killed
    IBinder binder;      // interface for clients that bind
    boolean allowRebind; // indicates whether onRebind should be used

    @Override
    public void onCreate() {
        // The service is being created
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // The service is starting, due to a call to startService()
        return startMode;
    }
    @Override
    public IBinder onBind(Intent intent) {
        // A client is binding to the service with bindService()
        return binder;
    }
    @Override
    public boolean onUnbind(Intent intent) {
        // All clients have unbound with unbindService()
        return allowRebind;
    }
    @Override
    public void onRebind(Intent intent) {
        // A client is binding to the service with bindService(),
        // after onUnbind() has already been called
    }
    @Override
    public void onDestroy() {
        // The service is no longer used and is being destroyed
    }
}

Not: Etkinlik yaşam döngüsü geri çağırma yöntemlerinin aksine, bu geri çağırma yöntemlerinin üst sınıf uygulamasını çağırmak gerekmez.

Şekil 2. Hizmet yaşam döngüsü. Soldaki diyagram hizmetin startService() ile oluşturulduğu andaki yaşam döngüsünü, sağdaki şema ise hizmetin oluşturulduğu andaki yaşam döngüsünü gösterir bindService() ile.

Şekil 2'de bir hizmete ilişkin genel geri çağırma yöntemleri gösterilmiştir. Şekil birbirinden ayrılsa da ve bunların startService() tarafından oluşturulan oluşturan: bindService(), sakla nasıl başlatıldığına bakılmaksızın tüm hizmetlerin müşterilerin ona bağlanmasına izin verebileceğini unutmayın. Başlangıçta onStartCommand() ile başlatılan bir hizmet (startService() arayan bir istemci tarafından) onBind() numaralı telefonu aramaya devam edebilir (bir müşteri bindService()) tıklayın.

Bu yöntemleri uygulayarak, hizmetin işleyiş şekline ilişkin iç içe yerleştirilmiş bu iki döngüyü, yaşam döngüsü:

  • Bir hizmetin tüm kullanım ömrü, onCreate() uygulamasının çağrıldığı an ile onDestroy() ürününün döndürdüğü zaman arasında gerçekleşir. Bir hizmette olduğu gibi, bir hizmet de ilk kurulumunu onCreate() ve kalan tüm kaynakları onDestroy() ürününde serbest bırakır. Örneğin, müzik çalma hizmeti, onCreate() içinde müziğin çalındığı ileti dizisini oluşturabilir ve ardından onDestroy() ürününde ileti dizisini durdurabilir.

    Not: onCreate() ve onDestroy() yöntemleri, bunlar startService() veya bindService() tarafından oluşturuldu.

  • Bir hizmetin etkin kullanım ömrü, onStartCommand() veya onBind() çağrılarıyla başlar. Her yönteme, startService() veya bindService() yöntemine geçirilen Intent verilir.

    Hizmet başlatılırsa etkin kullanım ömrü, hizmetin ömrü boyunca sona erer (hizmet, onStartCommand() iadesinden sonra bile etkin kalır). Hizmet bağlıysa onUnbind() geri döndüğünde etkin kullanım ömrü sona erer.

Not: Başlatılan bir hizmet, stopSelf() veya stopService() için ilgili bir geri çağırma yoktur. hizmet (onStop() geri araması yoktur). Hizmet bir istemciye bağlı olmadığı sürece hizmet durdurulduğunda sistem tarafından yok edilir. Alınan tek geri arama onDestroy().

Bağlama sağlayan bir hizmet oluşturma hakkında daha fazla bilgi edinmek için Sınır Hizmetler belgesini inceleyin. Burada onRebind() hakkında daha fazla bilgi bulabilirsiniz İş akışının yaşam döngüsünü yönetme bölümündeki bağlı bir hizmet olabilir.