İş isteklerini tanımlama

Başlangıç kılavuzunda basit bir WorkRequest oluşturmayı ve sıraya eklemeyi ele aldık.

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 çalışma planlama
  • Kablosuz bağlantı veya şarj etme gibi işle ilgili kısıtlamaları ayarlama
  • İşin yürütülmesinde minimum gecikmeyi garanti etme
  • Yeniden deneme ve geri çekilme stratejileri belirleyin
  • Giriş verilerini işe iletme
  • Etiketleri kullanarak ilgili çalışmaları birlikte gruplandırın

Genel bakış

İş, WorkManager'da bir WorkRequest ile tanımlanır. WorkManager ile çalışma planlayabilmek için önce bir WorkRequest nesnesi oluşturup bunu sıraya almanız gerekir.

Kotlin


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

Java


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

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

WorkRequest, kendisi 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 faydalıyken PeriodicWorkRequest belirli aralıklarla tekrarlanan işleri programlamak için daha uygundur.

Tek seferlik çalışma planlama

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 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ış çalışma planlama

WorkManager 2.7.0, hızlandırılmış çalışma kavramını ortaya çıkarmıştır. Bu, WorkManager'ın önemli işleri yürütmesine imkan tanırken sisteme de kaynaklara erişim üzerinde daha iyi kontrol sağlar.

Hızlandırılmış çalışma, aşağıdaki özellikler açısından dikkate değer:

  • Önem: Hızlandırılmış iş kıyafeti, kullanıcı için önemli olan veya kullanıcı tarafından başlatılan görevlerdir.
  • Hız: Hemen başlayan ve birkaç dakika içinde tamamlanan kısa görevler, hızlandırılmış çalışma için en uygunudur.
  • Kotalar: Ön planda yürütme süresini sınırlayan sistem düzeyinde kota, hızlandırılmış bir işin başlayıp başlayamayacağını belirler.
  • Güç Yönetimi: Pil Tasarrufu ve Doz gibi güç yönetimi kısıtlamalarının hızlandırılmış çalışmaları etkileme olasılığı daha düşüktür.
  • Gecikme: Sistemin mevcut iş yükünün, işlerini hızlıca tamamlaması koşuluyla hızlandırılmış işleri anında yürütür. Bu, iş yüklerinin gecikmeye duyarlı olduğu ve daha sonra yürütülmek üzere planlanamayacağı anlamına gelir.

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

Kotalar

Sistemin, bir işin yürütülebilmesi için önce yürütme süresini hızlandırılmış bir işe ayırması 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 kota yenilenene kadar hızlandırılmış çalışmayı yürütemezsiniz. Bu şekilde Android, kaynakları uygulamalar arasında daha etkili bir şekilde dengeleyebilir.

Bir uygulamanın kullanabileceği yürütme süresi, beklemede olan pakete ve işlemin önemine bağlıdır.

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

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

WorkManager 2.7'den başlayarak uygulamanız, bir WorkRequest uygulamasının hızlandırılmış bir iş kullanılarak olabildiğince hızlı çalışması gerektiğini belirtmek için setExpedited() yöntemini çağırabilir. Aşağıdaki kod snippet'i, setExpedited() öğesinin 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, OneTimeWorkRequest örneğini başlatırız ve setExpedited() çağrılır. Bu talep hızlandırılmış iş haline gelir. Kota izin veriyorsa arka planda hemen çalışmaya başlar. Kota kullanıldıysa OutOfQuotaPolicy parametresi, isteğin normal ve hızlandırılmamış çalışma gibi çalıştırılması gerektiğini belirtir.

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

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

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

Görevin hızlandırılmış bir iş olarak çalışmasını istiyorsanız tüm ListenableWorker yöntemleri getForegroundInfo yöntemini uygulamalıdır.

Android 12 veya sonraki sürümler hedeflendiğinde, ön plan hizmetlerini ilgili setForeground yöntemi aracılığıyla kullanabilirsiniz.

Çalışan

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

Bunu etkinleştirmek için WorkManager, gerektiğinde bir ForegroundService başlatmak için bildirim gösterebilmesi amacıyla uygulamanız gereken getForegroundInfoAsync() yöntemini sağlar.

Ortak Çalışan

CoroutineWorker kullanıyorsanız getForegroundInfo() uygulamanız gerekir. Ardından, doWork() içinde setForeground() adlı iş ortağına iletiriz. Bu işlem, Android 12'den önceki sürümlerinde bildirim 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 ne olacağını kontrol edebilirsiniz. Devam etmek için setExpedited() üzerinden geçebilirsiniz:

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

Örnek uygulama

WorkManager 2.7.0'ın hızlandırılmış işleri nasıl kullandığına dair tam bir örnek görmek için GitHub'daki WorkManagerSample bölümüne bakın.

Ertelenmiş hızlandırılmış çalışma

Sistem, hızlandırılmış bir 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ış işlerin başlangıcını erteleyebilir:

  • Yükleme: Sistem yükü çok fazladır. Bu durum, çok fazla iş çalışmaya devam ederken veya sistemde yeterli bellek olmadığında gerçekleşebilir.
  • Kota: Hızlandırılmış iş kotası sınırı aşıldı. Hızlandırılmış çalışma, Uygulama Beklemeye Alma Gruplarını temel alan bir kota sistemi kullanır ve belirli bir süre içinde maksimum yürütme süresini sınırlar. Hızlandırılmış çalışma için kullanılan kotalar, diğer arka plan iş türleri için kullanılan kotalardan daha kısıtlayıcıdır.

Periyodik çalışma planlama

Uygulamanız zaman zaman belirli işlerin periyodik olarak çalışması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 çalışan 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ı çalışma zamanlamasını hassas hale getiriyorsa PeriodicWorkRequest öğenizi Şekil 1'de gösterildiği gibi her aralık dönemi içinde esnek bir dönem içinde çalışacak şekilde yapılandırabilirsiniz.

Periyodik iş için esnek bir aralık ayarlayabilirsiniz. Bir tekrar aralığı ve tekrar aralığının sonunda belirli bir süreyi belirten esnek bir aralık tanımlarsınız. WorkManager, her döngüde esnek aralığın herhangi bir noktasında işinizi çalıştırmaya çalışır.

Şekil 1. Şema, çalışmanın çalışabileceği esnek dönemle birlikte tekrarlanan aralıkları gösterir.

Periyodik çalışmaları esnek dönemle tanımlamak için PeriodicWorkRequest öğesini oluştururken repeatInterval ile birlikte bir flexInterval geçirirsiniz. Esnek dönem, repeatInterval - flexInterval'de başlar ve aralığın sonuna kadar gider.

Aşağıda, her bir saatlik dönemin son 15 dakikası boyunca çalıştırılabilen periyodik çalışmaya 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ığı da PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS değerinden büyük veya bu değere eşit olmalıdır.

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

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

İşle ilgili kısıtlamalar

Sınırlamalar, ç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 Doğru değerine ayarlandığında, cihaz düşük pil modunda olduğunda çalışmanız çalışmaz.
Şarj gerektirir Doğru değerine ayarlandığında, çalışmanız yalnızca cihaz şarj olurken çalışır.
CihazBoşta Doğru değerine ayarlanırsa çalışmanın yürütülebilmesi için kullanıcının cihazının boşta olması gerekir. Bu özellik, aksi halde kullanıcının cihazında etkin olarak çalışan diğer uygulamalar üzerinde olumsuz performans etkisi yaratabilecek toplu işlemlerin çalıştırılması için yararlı olabilir.
Depolama Alanı Düşük Değil Doğru değerine ayarlandığında, kullanıcının cihazdaki depolama alanı çok azsa çalışmanız çalışmaz.

Bir kısıtlama grubu oluşturmak ve bunu bazı çalışmalarla ilişkilendirmek için Contraints.Builder() kullanarak bir Constraints örneği oluşturup WorkRequest.Builder() öğesine 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ı olduğunda çalışan 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 çalışır.

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

Geciken Çalışma

Çalışmanızda hiçbir kısıtlama yoksa veya çalışmanız sıraya alındığında tüm kısıtlamalar karşılanmışsa 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ıç gecikmesinden sonra başlamasını belirtebilirsiniz.

Aşağıda, çalışmanızı sıraya alındıktan en az 10 dakika sonra çalışacak şekilde nasıl ayarlayacağınıza dair bir örnek verilmiştir.

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 başlangıç gecikmesi de ayarlayabilirsiniz. Bu durumda, periyodik çalışmanızın yalnızca ilk çalıştırması gecikir.

Yeniden deneme ve geri yükleme politikası

WorkManager'ın çalışmanızı yeniden denemesini zorunlu tutarsanız çalışanınızdan Result.retry() kodunu döndürebilirsiniz. Daha sonra çalışmanız geri yükleme gecikmesine ve geri yükleme politikasına göre yeniden planlanır.

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

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

Her iş isteğinin bir geri yükleme politikası ve geri yükleme gecikmesi vardır. Varsayılan politika, 30 saniyelik gecikmeyle EXPONENTIAL politikasıdır, 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ğer olan 10 saniye olarak ayarlanmıştır. Politika LINEAR olduğundan yeniden deneme aralığı her yeni denemede yaklaşık 10 saniye artar. Örneğin, sonraki denemelerden sonra Result.retry() geri döndürülmeye devam ederse Result.retry() ile ilk çalıştırma 10 saniye sonra tekrar denenir, ardından 20, 30, 40 vb. Geri yükleme politikası EXPONENTIAL değerine ayarlanırsa yeniden deneme süresi dizisi 20, 40, 80 gibi değerlere daha yakın olur.

İş etiketini etiketle

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

Mantıksal açıdan birbiriyle bağlantılı bir grup çalışmanız varsa bu çalışma öğelerini etiketlemek de yararlı olabilir. Etiketleme, bir grup çalışma isteğiyle birlikte çalışabilmenizi sağlar.

Ö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 nasıl "temizleme" etiketi 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. Bu etiketler dahili olarak bir dizi dize olarak depolanır. WorkRequest ile ilişkilendirilen 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 ata

İşinizin çalışabilmesi için giriş verileri gerekebilir. Örneğin, bir resmin yüklenmesinin işlendiği çalışmalarda, resmin URI'sının giriş olarak yüklenmesi gerekebilir.

Giriş değerleri, bir Data nesnesinde anahtar/değer çiftleri olarak depolanır ve iş isteği üzerinde ayarlanabilir. WorkManager, işi yürütürken işinizin Data girdisini teslim eder. Worker sınıfı Worker.getInputData() yöntemini çağırarak giriş bağımsız değişkenlerine erişebilir. Aşağıdaki kod, giriş verisi gerektiren bir Worker örneğini nasıl oluşturabileceğinizi ve bu örneği 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ı döndürülen değer çıkışı için de 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

Eyaletler ve gözlem sayfasında çalışma durumları ve işinizin ilerlemesini nasıl izleyeceğiniz hakkında daha fazla bilgi edinebilirsiniz.