İş isteklerini tanımlama

Başlangıç kılavuzunda, basit bir WorkRequest oluşturma ve sıraya ekleme konuları ele alınmıştır.

Bu kılavuzda, aşağıdaki gibi yaygın kullanım alanlarını ele almak için WorkRequest nesnelerini tanımlamayı ve özelleştirmeyi öğreneceksiniz:

  • Tek seferlik ve yinelenen işler programlama
  • Kablosuz ağ veya şarj etme gibi iş kısıtlamaları ayarlayın
  • İşin yürütülmesinde minimum gecikme yaşanmasını garanti etmek
  • Yeniden deneme ve geri alma stratejileri belirleyin
  • Giriş verilerini işe aktarın
  • Etiketleri kullanarak ilgili işleri gruplandırın

Genel bakış

İş Yöneticisi, WorkRequest aracılığıyla tanımlanır. WorkManager ile herhangi bir çalışmayı planlamak için önce bir WorkRequest nesnesi oluşturmanız ve ardından bunu sıraya koymanız gerekir.

Kotlin


val myWorkRequest = ...
WorkManager.getInstance(myContext).enqueue(myWorkRequest)

Java


WorkRequest myWorkRequest = ...
WorkManager.getInstance(myContext).enqueue(myWorkRequest);

WorkRequest nesnesi, WorkManager'ın işinizi planlamak ve çalıştırmak için ihtiyaç duyduğu tüm bilgileri içerir. Çalışmanızın çalışması için karşılanması gereken kısıtlamalar, gecikmeler veya yinelenen aralıklar gibi planlama bilgileri, yeniden yapılandırmayı yeniden deneme ve çalışmanız buna dayanıyorsa giriş verilerini içerebilir.

WorkRequest soyut bir temel sınıftır. Bu sınıfın, isteği oluşturmak için kullanabileceğiniz iki türetilmiş uygulaması vardır: OneTimeWorkRequest ve PeriodicWorkRequest. Adlarından da anlaşılacağı gibi OneTimeWorkRequest, tekrarlanmayan işleri planlamak için kullanılırken PeriodicWorkRequest belirli aralıklarla tekrarlanan işleri planlamak için daha uygundur.

Tek seferlik çalışma programlama

Ek yapılandırma gerektirmeyen basit işler için from statik yöntemini kullanın:

Kotlin


val myWorkRequest = OneTimeWorkRequest.from(MyWork::class.java)

Java


WorkRequest myWorkRequest = OneTimeWorkRequest.from(MyWork.class);

Daha karmaşık işler için bir oluşturucu kullanabilirsiniz:

Kotlin

val uploadWorkRequest: WorkRequest =
   OneTimeWorkRequestBuilder<MyWork>()
       // Additional configuration
       .build()

Java

WorkRequest uploadWorkRequest =
   new OneTimeWorkRequest.Builder(MyWork.class)
       // Additional configuration
       .build();

Hızlandırılmış işler için zaman belirleyin

WorkManager 2.7.0 hızlandırılmış çalışma kavramını ortaya attı. Bu sayede WorkManager, önemli işleri yürütürken sisteme kaynaklara erişim üzerinde daha iyi kontrol verir.

Hızlandırılmış çalışmalarda şu özellikler öne çıkar:

  • Önem: Hızlandırılmış çalışmalar, kullanıcı için önemli olan veya kullanıcı tarafından başlatılan görevlere uygundur.
  • Hız: Hızlandırılmış çalışmalar, hemen başlayıp birkaç dakika içinde tamamlanan kısa görevler için idealdir.
  • Kotalar: Ön planda yürütme süresini sınırlayan sistem düzeyindeki bir kota, hızlandırılmış bir işin başlatılıp başlatılamayacağını belirler.
  • Güç Yönetimi: Pil Tasarrufu ve Doz gibi güç yönetimi kısıtlamalarının hızlandırılmış işi etkileme olasılığı daha düşüktür.
  • Gecikme: Sistem, mevcut iş yükünün buna imkan tanıması koşuluyla hızlandırılmış işi hemen yürütür. Bu, gecikmelere duyarlı oldukları ve daha sonra yürütme için planlanamaz.

Hızlandırılmış işin olası bir kullanım alanı, kullanıcı mesaj veya ekli bir resim göndermek istediğinde sohbet uygulaması olabilir. Benzer şekilde, ödeme veya abonelik akışını yöneten bir uygulama da hızlandırılmış işleri kullanmak isteyebilir. Bunun nedeni, bu görevlerin kullanıcı için önemli olması, arka planda hızlı yürütülmesi, hemen başlatılması ve kullanıcı uygulamayı kapatsa bile yürütülmeye devam etmesinin gerekmesidir.

Kotalar

Sistemin, yürütme işlemini tamamlamış bir işin çalışabilmesi için önce bu işe ayrılması gerekir. Yürütme süresi sınırsız değildir. Bunun yerine, her uygulama bir yürütme süresi kotası alır. Uygulamanız yürütme süresini kullandığında ve ayrılan kotasına ulaştığında artık kota yenilenene kadar hızlandırılmış işleri yürütemezsiniz. Bu sayede Android, uygulamalar arasında kaynakları daha etkili bir şekilde dengeleyebilir.

Bir uygulamanın kullanılabilmesi için gereken yürütme süresi, bekleme paketine ve işlemin önemine bağlıdır.

Yürütme kotası, hızlandırılmış bir işin hemen çalışmasına izin vermediğinde ne olacağını belirleyebilirsiniz. Ayrıntılı bilgi için aşağıdaki snippet'lere bakın.

Hızlandırılmış işleri yürütme

WorkManager 2.7'den itibaren uygulamanız, setExpedited() çağırarak WorkRequest ürününün hızlandırılmış bir iş kullanarak mümkün olduğunca hızlı çalışması gerektiğini bildirebilir. Aşağıdaki kod snippet'i, setExpedited() özelliğinin nasıl kullanılacağına dair bir örnek sunar:

Kotlin

val request = OneTimeWorkRequestBuilder<SyncWorker>()
    .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
    .build()

WorkManager.getInstance(context)
    .enqueue(request)

Java

OneTimeWorkRequest request = new OneTimeWorkRequestBuilder<T>()
    .setInputData(inputData)
    .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
    .build();

Bu örnekte, bir OneTimeWorkRequest örneğini başlatıyor ve bu örnekte setExpedited() yöntemini çağırıyoruz. Bu istek hızlandırılmış iş haline gelir. Kota izin veriyorsa hemen arka planda çalışmaya başlar. Kota kullanılmışsa OutOfQuotaPolicy parametresi, isteğin normal, hızlandırılmamış çalışma gibi çalıştırılması gerektiğini belirtir.

Geriye dönük uyumluluk ve ön plan hizmetleri

Hızlandırılmış işlerin geriye dönük uyumluluğu sağlamak amacıyla WorkManager, Android 12'den eski platform sürümlerinde bir ön plan hizmeti çalıştırabilir. Ön plan hizmetleri kullanıcıya bildirim gösterebilir.

Worker'ınızdaki getForegroundInfoAsync() ve getForegroundInfo() yöntemleri, WorkManager'ın, Android 12'den önce setExpedited() yöntemini çağırdığınızda bildirim göstermesini sağlar.

Görevin hızlandırılmış bir iş olarak çalışmasını talep etmek istiyorsanız herhangi bir ListenableWorker, getForegroundInfo yöntemini uygulamalıdır.

Android 12 veya sonraki sürümleri hedeflerken, ön plan hizmetlerini ilgili setForeground yöntemiyle kullanmaya devam edebilirsiniz.

Çalışan

Çalışanlar, yaptıkları işin hızlandırılıp hızlandırılmadığını bilmiyor. Ancak bir WorkRequest hızlandırıldığında çalışanlar Android'in bazı sürümlerinde bildirim görüntüleyebilir.

WorkManager, bunu sağlamak için getForegroundInfoAsync() yöntemini sağlar. Bu yöntemi uygulayarak WorkManager'ın gerektiğinde sizin için bir ForegroundService başlatması için bildirim görüntüleyebilmesi gerekir.

Eş yordam çalışanı

CoroutineWorker kullanıyorsanız getForegroundInfo() uygulamanız gerekir. Daha sonra doWork() içinde setForeground() hizmetine iletirsiniz. Bu işlem, bildirimi Android 12'den önceki sürümlerinde oluşturur.

Aşağıdaki örneği inceleyin:

  class ExpeditedWorker(appContext: Context, workerParams: WorkerParameters):
   CoroutineWorker(appContext, workerParams) {

   override suspend fun getForegroundInfo(): ForegroundInfo {
       return ForegroundInfo(
           NOTIFICATION_ID, createNotification()
       )
   }

   override suspend fun doWork(): Result {
       TODO()
   }

    private fun createNotification() : Notification {
       TODO()
    }

}

Kota politikaları

Uygulamanız yürütme kotasına ulaştığında hızlandırılmış işin nasıl ele alınacağını kontrol edebilirsiniz. Devam etmek için setExpedited() ayarını geçirebilirsiniz:

  • OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST izni bulunur. Bu durum, işin normal iş isteği olarak çalışmasına neden olur. Yukarıdaki snippet bunu göstermektedir.
  • OutOfQuotaPolicy.DROP_WORK_REQUEST. Bu, yeterli kota olmadığında isteğin iptal edilmesine neden olur.

Örnek uygulama

WorkManager 2.7.0'ın hızlandırılmış işi nasıl kullandığına dair eksiksiz bir örnek görmek için GitHub'da WorkManagerSample'ı inceleyin.

Ertelenen, hızlandırılmış çalışma

Sistem, belirli bir hızlandırılmış işi, iş çağrıldıktan sonra mümkün olan en kısa sürede yürütmeye çalışır. Ancak diğer iş türlerinde olduğu gibi sistem aşağıdaki durumlarda olduğu gibi yeni hızlandırılmış çalışmaların başlamasını erteleyebilir:

  • Yükle: Sistem yükü çok fazla. Bu durum, zaten çok fazla işin çalıştığı veya sistemde yeterli bellek olmaması durumunda ortaya çıkabilir.
  • Kota: Hızlandırılmış iş kotası sınırı aşıldı. Hızlandırılmış çalışmada, Uygulama Bekleme Paketleri'ne dayalı bir kota sistemi kullanılır ve periyodik bir zaman aralığı dahilinde maksimum yürütme süresini sınırlar. Hızlandırılmış işler için kullanılan kotalar, diğer arka plan işi türleri için kullanılan kotalardan daha kısıtlayıcıdır.

Periyodik işler planlayın

Uygulamanız zaman zaman belirli işlerin düzenli olarak çalıştırılmasını gerektirebilir. Örneğin, verilerinizi düzenli olarak yedeklemek, uygulamanızdaki yeni içerikleri indirmek veya günlükleri bir sunucuya yüklemek isteyebilirsiniz.

Düzenli olarak yürütülen bir WorkRequest nesnesi oluşturmak için PeriodicWorkRequest öğesini şu şekilde kullanabilirsiniz:

Kotlin


val saveRequest =
       PeriodicWorkRequestBuilder<SaveImageToFileWorker>(1, TimeUnit.HOURS)
    // Additional configuration
           .build()

Java


PeriodicWorkRequest saveRequest =
       new PeriodicWorkRequest.Builder(SaveImageToFileWorker.class, 1, TimeUnit.HOURS)
           // Constraints
           .build();

Bu örnekte, çalışma bir saatlik aralıklarla planlanmıştır.

Aralık süresi, tekrarlar arasındaki minimum süre olarak tanımlanır. Çalışanın tam olarak yürütüleceği zaman, WorkRequest nesnenizde kullandığınız kısıtlamalara ve sistem tarafından gerçekleştirilen optimizasyonlara bağlıdır.

Esnek çalıştırma aralıkları

Çalışmanızın yapısı nedeniyle çalışma zamanlaması hassas hale geliyorsa PeriodicWorkRequest öğenizi, Şekil 1'de gösterildiği gibi her aralık dönemi içinde bir esnek dönem içinde çalışacak şekilde yapılandırabilirsiniz.

Periyodik işler için esnek zaman aralığı ayarlayabilirsiniz. Bir tekrarlama aralığı ve tekrarlama aralığının sonunda belirli bir süreyi belirten bir esnek aralık tanımlarsınız. WorkManager, her döngüdeki esnek aralık sırasında bir noktada işinizi çalıştırmayı dener.

Şekil 1. Şema, işin çalışabileceği esnek dönemle tekrar eden aralıkları gösterir.

Esnek dönemli periyodik çalışmayı tanımlamak için, PeriodicWorkRequest oluştururken repeatInterval ile birlikte bir flexInterval iletirsiniz. Esnek dönem, repeatInterval - flexInterval ile başlar ve aralığın sonuna kadar devam eder.

Aşağıda, her saatlik bir sürenin son 15 dakikası boyunca gerçekleştirilebilecek periyodik çalışmalara bir örnek verilmiştir.

Kotlin


val myUploadWork = PeriodicWorkRequestBuilder<SaveImageToFileWorker>(
       1, TimeUnit.HOURS, // repeatInterval (the period cycle)
       15, TimeUnit.MINUTES) // flexInterval
    .build()

Java


WorkRequest saveRequest =
       new PeriodicWorkRequest.Builder(SaveImageToFileWorker.class,
               1, TimeUnit.HOURS,
               15, TimeUnit.MINUTES)
           .build();

Tekrar aralığı PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS veya daha büyük, esnek aralık da PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS değerine eşit ya da daha büyük olmalıdır.

Kısıtlamaların Periyodik Çalışma Üzerindeki Etki

Periyodik çalışmaya kısıtlamalar uygulayabilirsiniz. Örneğin, iş isteğinize, çalışmanın yalnızca kullanıcının cihazı şarj olurken çalışacağı şekilde bir kısıtlama ekleyebilirsiniz. Bu durumda, tanımlanan tekrarlama aralığı geçse bile PeriodicWorkRequest bu koşul karşılanana kadar çalışmaz. Bu durum, çalışmanızın belirli bir çalışmasının gecikmesine veya hatta çalıştırma aralığı içinde koşullar karşılanmazsa atlanmasına neden olabilir.

İş kısıtlamaları

Kısıtlamalar, çalışmanın en uygun koşullar karşılanana kadar ertelenmesini sağlar. Aşağıdaki kısıtlamalar WorkManager tarafından kullanılabilir.

Ağ Türü Çalışmanızın çalışması için gereken ağ türünü kısıtlar. Örneğin, kablosuz ağ (UNMETERED).
Pil Düşük Değil Doğru değerine ayarlandığında cihaz düşük pil modunda olduğunda çalışmanız çalışmaz.
Şarj Gerekiyor Doğru değerine ayarlanırsa çalışmanız yalnızca cihaz şarj olurken çalışır.
Cihaz Boşta Politika, Doğru değerine ayarlandığında çalışmanın çalışması için kullanıcının cihazının boşta olması gerekir. Bu özellik, kullanıcının cihazında etkin olarak çalışan diğer uygulamalar üzerinde performansı olumsuz yönde etkileyebilecek toplu işlemleri çalıştırırken faydalı olabilir.
Depolama Alanı Düşük Değil Politika, Doğru değerine ayarlandığında kullanıcının cihazdaki depolama alanı çok azsa çalışmanız çalışmaz.

Kısıtlama grubu oluşturmak ve bunu bir çalışmayla ilişkilendirmek için Contraints.Builder() kullanarak bir Constraints örneği oluşturun ve bunu WorkRequest.Builder() öğenize atayın.

Örneğin, aşağıdaki kod yalnızca kullanıcının cihazı hem şarj olurken hem de kablosuz ağa bağlıyken çalıştırılan bir iş isteği oluşturur:

Kotlin


val constraints = Constraints.Builder()
   .setRequiredNetworkType(NetworkType.UNMETERED)
   .setRequiresCharging(true)
   .build()

val myWorkRequest: WorkRequest =
   OneTimeWorkRequestBuilder<MyWork>()
       .setConstraints(constraints)
       .build()

Java


Constraints constraints = new Constraints.Builder()
       .setRequiredNetworkType(NetworkType.UNMETERED)
       .setRequiresCharging(true)
       .build();

WorkRequest myWorkRequest =
       new OneTimeWorkRequest.Builder(MyWork.class)
               .setConstraints(constraints)
               .build();

Birden fazla kısıtlama belirtildiğinde çalışmanız yalnızca tüm kısıtlamalar karşılandığında gerçekleştirilir.

Çalışmanız devam ederken bir kısıtlamanın karşılanmaması durumunda WorkManager, çalışanınızı durdurur. Çalışma, tüm koşullar karşılandığında yeniden denenir.

Gecikmeli Çalışma

Çalışmanızda herhangi bir kısıtlama olmaması veya çalışmanız sıraya alındığında tüm kısıtlamaların karşılanması halinde sistem, çalışmayı hemen çalıştırmayı seçebilir. Çalışmanın hemen çalıştırılmasını istemiyorsanız çalışmanızın minimum bir başlangıç gecikmesinin ardından başlamasını belirtebilirsiniz.

Çalışmanızı sıraya alındıktan en az 10 dakika sonra çalışacak şekilde nasıl ayarlayacağınıza dair bir örneği aşağıda bulabilirsiniz.

Kotlin


val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
   .setInitialDelay(10, TimeUnit.MINUTES)
   .build()

Java


WorkRequest myWorkRequest =
      new OneTimeWorkRequest.Builder(MyWork.class)
               .setInitialDelay(10, TimeUnit.MINUTES)
               .build();

Örnekte, OneTimeWorkRequest için ilk gecikmenin nasıl ayarlanacağı gösterilse de PeriodicWorkRequest için bir ilk gecikme süresi de ayarlayabilirsiniz. Bu durumda, periyodik işinizin yalnızca ilk çalıştırması gecikir.

Yeniden deneme ve geri alma politikası

WorkManager'ın işinizi yeniden denemesini zorunlu tutarsanız çalışanınızdan Result.retry() değerini geri döndürebilirsiniz. Daha sonra çalışmanız bir geri yükleme gecikmesi ve geri alma politikasına göre yeniden planlanır.

  • Geri yükleme gecikmesi, ilk denemeden sonra çalışmanızı yeniden denemeden önce beklenecek minimum süreyi belirtir. Bu değer 10 saniyeden az olamaz (veya MIN_BACKOFF_MILLIS).

  • Geri yükleme politikası, sonraki yeniden deneme denemeleri için geri yükleme gecikmesinin zaman içinde nasıl artması gerektiğini tanımlar. WorkManager, LINEAR ve EXPONENTIAL olmak üzere 2 geri yükleme politikasını destekler.

Her iş isteğinin bir geri alma politikası ve geri alma gecikmesi vardır. Varsayılan politika, 30 saniyelik gecikmeyle EXPONENTIAL şeklindedir ancak iş isteği yapılandırmanızda bunu geçersiz kılabilirsiniz.

Aşağıda, geri yükleme gecikmesini ve politikasını özelleştirmeyle ilgili bir örnek verilmiştir.

Kotlin


val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
   .setBackoffCriteria(
       BackoffPolicy.LINEAR,
       OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
       TimeUnit.MILLISECONDS)
   .build()

Java


WorkRequest myWorkRequest =
       new OneTimeWorkRequest.Builder(MyWork.class)
               .setBackoffCriteria(
                       BackoffPolicy.LINEAR,
                       OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
                       TimeUnit.MILLISECONDS)
               .build();

Bu örnekte, minimum geri yükleme gecikmesi izin verilen minimum değere (10 saniye) ayarlanmıştır. Politika LINEAR olduğundan yeniden deneme aralığı her yeni denemede yaklaşık 10 saniye artırılır. Örneğin, Result.retry() ile biten ilk çalıştırma 10 saniye sonra tekrar denenir. Ardından 20, 30, 40 ve 20, 40 saniye gibi devam eder. Çalışma, sonraki denemelerden sonra geri gelmeye devam ederse Result.retry(). Geri yükleme politikası EXPONENTIAL değerine ayarlanırsa yeniden deneme süresi dizisi 20, 40, 80 vb.'ye daha yakın olur.

Etiket işi

Her iş isteğinin benzersiz bir tanımlayıcısı vardır. Bu tanımlayıcı, daha sonra çalışmayı iptal etmek veya ilerleme durumunu gözlemlemek için kullanılabilir.

Mantıksal olarak ilişkili bir çalışma grubunuz varsa bu çalışma öğelerini etiketlemek de yararlı olabilir. Etiketleme, bir grup iş isteğiyle birlikte çalışmanıza olanak tanır.

Örneğin, WorkManager.cancelAllWorkByTag(String) belirli bir etikete sahip tüm iş isteklerini iptal eder ve WorkManager.getWorkInfosByTag(String), mevcut çalışma durumunu belirlemek için kullanılabilecek WorkInfo nesnelerinin bir listesini döndürür.

Aşağıdaki kod, işinize bir "temizlik" etiketini nasıl ekleyebileceğinizi gösterir:

Kotlin


val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
   .addTag("cleanup")
   .build()

Java


WorkRequest myWorkRequest =
       new OneTimeWorkRequest.Builder(MyWork.class)
       .addTag("cleanup")
       .build();

Son olarak, tek bir iş isteğine birden fazla etiket eklenebilir. Dahili olarak bu etiketler bir dize grubu olarak depolanır. WorkRequest ile ilişkili etiket grubunu almak için WorkInfo.getTags() işlevini kullanabilirsiniz.

Worker sınıfınızdan, etiket grubunu ListenableWorker.getTags() aracılığıyla alabilirsiniz.

Giriş verilerini atayın

Çalışmanız için giriş verileri gerekebilir. Örneğin, resim yüklemeyi tutan işler için, resmin URI'sinin giriş olarak yüklenmesi gerekebilir.

Giriş değerleri, Data nesnesinde anahtar/değer çiftleri olarak depolanır ve iş isteğinde ayarlanabilir. WorkManager, işi yürütürken Data girişini çalışmanıza iletir. Worker sınıfı, Worker.getInputData() yöntemini çağırarak giriş bağımsız değişkenlerine erişebilir. Aşağıdaki kod, giriş verileri gerektiren bir Worker örneğini nasıl oluşturabileceğinizi ve iş isteğinizde nasıl göndereceğinizi gösterir.

Kotlin


// Define the Worker requiring input
class UploadWork(appContext: Context, workerParams: WorkerParameters)
   : Worker(appContext, workerParams) {

   override fun doWork(): Result {
       val imageUriInput =
           inputData.getString("IMAGE_URI") ?: return Result.failure()

       uploadFile(imageUriInput)
       return Result.success()
   }
   ...
}

// Create a WorkRequest for your Worker and sending it input
val myUploadWork = OneTimeWorkRequestBuilder<UploadWork>()
   .setInputData(workDataOf(
       "IMAGE_URI" to "http://..."
   ))
   .build()

Java


// Define the Worker requiring input
public class UploadWork extends Worker {

   public UploadWork(Context appContext, WorkerParameters workerParams) {
       super(appContext, workerParams);
   }

   @NonNull
   @Override
   public Result doWork() {
       String imageUriInput = getInputData().getString("IMAGE_URI");
       if(imageUriInput == null) {
           return Result.failure();
       }

       uploadFile(imageUriInput);
       return Result.success();
   }
   ...
}

// Create a WorkRequest for your Worker and sending it input
WorkRequest myUploadWork =
      new OneTimeWorkRequest.Builder(UploadWork.class)
           .setInputData(
               new Data.Builder()
                   .putString("IMAGE_URI", "http://...")
                   .build()
           )
           .build();

Benzer şekilde, Data sınıfı bir dönüş değeri oluşturmak için kullanılabilir. Giriş ve çıkış verileri, giriş parametreleri ve döndürülen değerler bölümünde daha ayrıntılı olarak ele alınmıştır.

Sonraki adımlar

Durumlar ve gözlemler sayfasında çalışma durumları ve çalışmanızın ilerlemesini nasıl izleyeceğiniz hakkında daha fazla bilgi edinebilirsiniz.