Başlangıç kılavuzunda basit bir WorkRequest
oluşturma ve sıraya ekleme işlemleri 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 gerektirme gibi iş kısıtlamaları belirleme
- İşin yürütülmesinde minimum gecikme garantisi
- Yeniden deneme ve geri çekilme stratejilerini ayarlama
- Giriş verilerini işe aktarma
- Etiketleri kullanarak ilgili çalışmaları bir arada gruplandırma
Genel Bakış
Work, WorkManager'da bir WorkRequest
aracılığıyla tanımlanır. WorkManager ile herhangi bir işi planlamak için önce bir WorkRequest
nesnesi oluşturmanız ve ardından bu nesneyi sıraya eklemeniz 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. İşinizin çalıştırılması için karşılanması gereken kısıtlamaları, gecikmeler veya tekrarlanan aralıklar gibi planlama bilgilerini, yeniden deneme yapılandırmasını içerir ve işiniz bu bilgilere dayanıyorsa giriş verilerini de 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ıdır. PeriodicWorkRequest
ise belirli aralıklarla tekrarlanan işleri planlamak için daha uygundur.
Tek seferlik işleri planlama
Ek yapılandırma gerektirmeyen basit işler için statik yöntemi from
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();
Yüksek öncelikli işleri planlama
WorkManager 2.7.0, yüksek öncelikli iş kavramını kullanıma sundu. Bu sayede WorkManager, önemli işleri yürütürken sisteme kaynaklara erişim konusunda daha fazla kontrol sağlar.
Yüksek öncelikli işler aşağıdaki özelliklerle dikkat çeker:
- Önem: Hızlandırılmış çalışma, kullanıcı için önemli olan veya kullanıcı tarafından başlatılan görevler için uygundur.
- Hız: Hızlandırılmış çalışma, hemen başlayan ve birkaç dakika içinde tamamlanan kısa görevler için en uygun yöntemdir.
- Kotalar: Ön planda yürütme süresini sınırlayan sistem düzeyinde 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 bunu yapmasına izin vermesi koşuluyla hızlandırılmış işi hemen yürütür. Bu, gecikme duyarlı oldukları ve daha sonra yürütülmek üzere planlanamayacakları anlamına gelir.
Hızlandırılmış çalışmanın potansiyel bir kullanım alanı, kullanıcının bir mesaj veya ek resim göndermek istediği sohbet uygulaması olabilir. Benzer şekilde, ödeme veya abonelik akışını yöneten bir uygulama da hızlandırılmış çalışmayı kullanabilir. 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
Sistem, hızlandırılmış bir işin çalıştırılabilmesi için yürütme süresi ayırmalıdır. Yürütme süresi sınırsız değildir. Bunun yerine, her uygulamaya bir yürütme süresi kotası verilir. 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 sayede Android, kaynakları uygulamalar arasında daha etkili bir şekilde dengeleyebilir.
Bir uygulamanın kullanabileceği yürütme süresi, bekleme paketine ve işleme ö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ılar için aşağıdaki snippet'lere bakın.
Yüksek öncelikli işleri yürütme
WorkManager 2.7'den itibaren uygulamanız, bir WorkRequest
'un hızlandırılmış iş kullanarak mümkün olduğunca hızlı çalışacağını beyan etmek için setExpedited()
'ü çağırabilir. Aşağıdaki kod snippet'inde setExpedited()
işlevinin nasıl kullanılacağıyla ilgili bir örnek verilmiştir:
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ıp üzerinde setExpedited()
işlevini çağırıyoruz. Bu talep, hızlandırılmış çalışma olarak kabul edilir. Kota izin veriyorsa hemen arka planda çalışmaya başlar. Kota kullanıldıysa OutOfQuotaPolicy
parametresi, isteğin normal ve hızlandırılmamış çalışma olarak çalıştırılması gerektiğini gösterir.
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.
İşleyicinizdeki getForegroundInfoAsync()
ve getForegroundInfo()
yöntemleri, Android 12'den önce setExpedited()
çağrısında bulunduğunuzda WorkManager'ın bildirim göstermesini sağlar.
Görevin hızlandırılmış iş olarak çalışmasını talep etmek istiyorsanız tüm ListenableWorker
'ler getForegroundInfo
yöntemini uygulamalıdır.
Android 12 veya sonraki sürümleri hedeflediğinizde ön plan hizmetleri, ilgili setForeground
yöntemi aracılığıyla kullanılabilir durumda kalır.
Ç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 etkinleştirmek için getForegroundInfoAsync()
yöntemini sağlar. WorkManager'ın gerektiğinde sizin için bir ForegroundService
başlatma bildirimi gösterebilmesi için bu yöntemi uygulamanız gerekir.
Eş yordam
CoroutineWorker
kullanıyorsanız getForegroundInfo()
'ü uygulamanız gerekir. Ardından, doWork()
içinde setForeground()
'e iletebilirsiniz. Bu işlem, Android 12'den önceki sürümlerde bildirimi 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ış çalışmaya ne olacağını kontrol edebilirsiniz. Devam etmek için setExpedited()
ayarını geçirebilirsiniz:
OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST
, bu da işin sıradan bir iş isteği olarak çalışmasına neden olur. Yukarıdaki snippet'te bu gösterilmektedir.OutOfQuotaPolicy.DROP_WORK_REQUEST
, yeterli kota yoksa isteğin iptal edilmesine neden olur.
Örnek uygulama
WorkManager 2.7.0'ın hızlandırılmış işi nasıl kullandığına dair tam bir örnek görmek için GitHub'daki WorkManagerSample'e göz atın.
Ertelenen, hızlandırılmış çalışma
Sistem, belirli bir hızlandırılmış işi çağrıldıktan sonra en kısa sürede yürütmeye çalışır. Ancak diğer iş türlerinde olduğu gibi sistem, yeni hızlandırılmış çalışmaların başlangıcını erteleyebilir. Örneğin:
- Yük: Sistem yükü çok yüksek. Bu durum, çok fazla iş zaten çalışıyorken veya sistemde yeterli bellek olmadığında ortaya çıkabilir.
- Kota: Hızlandırılmış iş kotası sınırı aşıldı. Hızlandırılmış çalışma, uygulama bekleme gruplarına dayalı bir kota sistemi kullanır ve maksimum yürütme süresini bir zaman aralığında sınırlandırır. Hızlandırılmış çalışma 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şleri planlama
Uygulamanız bazen belirli işlemlerin düzenli olarak yapılmasını gerektirebilir. Örneğin, verilerinizi düzenli olarak yedeklemek, uygulamanıza yeni içerik 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ıkla planlanmıştır.
Aralık süresi, tekrarlar arasındaki minimum süre olarak tanımlanır. İşleyicinin tam olarak ne zaman çalıştırılacağı, WorkRequest nesnenizde kullandığınız kısıtlamalara ve sistem tarafından yapılan optimizasyonlara bağlıdır.
Esnek çalışma aralıkları
Çalışmanızın doğası nedeniyle çalışma zamanlamasına duyarlıysa PeriodicWorkRequest
'ünüzü, Şekil 1'de gösterildiği gibi her aralık döneminde bir esnek dönemde çalışacak şekilde yapılandırabilirsiniz.
Şekil 1. Şemada, işin çalışabileceği esnek dönemle birlikte yinelenen aralıklar gösterilmektedir.
Esnek dönem içeren periyodik çalışmayı tanımlamak için PeriodicWorkRequest
oluştururken repeatInterval
ile birlikte bir flexInterval
iletmeniz gerekir. Esnek dönem repeatInterval - flexInterval
'te başlar ve aralığın sonuna kadar devam eder.
Aşağıda, her bir saatlik dönemin son 15 dakikasında çalıştırılabilen düzenli bir çalışma örneği 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ığı ise PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS
veya daha büyük olmalıdır.
Kısıtlamaların Düzenli Çalışma Üzerindeki Etkisi
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 tekrar aralığı geçse bile PeriodicWorkRequest
bu koşul karşılanana kadar çalışmaz. Bu durum, çalışmanızın belirli bir çalıştırmasının gecikmesine veya çalıştırma aralığında koşullar karşılanmıyorsa atlanmasına neden olabilir.
Çalışma 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 (UNMETERED ).
|
BatteryNotLow | 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. |
DeviceIdle | 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, kullanıcının cihazında etkin olarak çalışan diğer uygulamalar üzerinde olumsuz bir performans etkisi olabilecek toplu işlemleri çalıştırmak için yararlı olabilir. |
StorageNotLow | Politika, Doğru değerine ayarlandığında kullanıcının cihazdaki depolama alanı çok azsa çalışmanız çalışmaz. |
Bir dizi kısıtlama oluşturmak ve bu kısıtlamaları bir çalışmayla ilişkilendirmek için Contraints.Builder()
kullanarak bir Constraints
örneği oluşturun ve bu örneği WorkRequest.Builder()
'inize 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.
İşiniz çalışırken bir kısıtlamanın karşılanmaması durumunda WorkManager, işleyicinizi 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ın, sıraya eklendikten en az 10 dakika sonra çalışacak şekilde nasıl ayarlanacağına dair bir örnek aşağıda 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, bir OneTimeWorkRequest
için ilk gecikmenin nasıl ayarlanacağı gösterilmektedir. PeriodicWorkRequest
için de ilk gecikme ayarlayabilirsiniz. Bu durumda, yalnızca düzenli işinizin ilk çalıştırması gecikecektir.
Yeniden deneme ve geri alma politikası
WorkManager'ın çalışmanızı yeniden denemesini istiyorsanız işleyicinizden Result.retry()
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 beklemeniz gereken minimum süreyi belirtir. Bu değer en az 10 saniye (veya MIN_BACKOFF_MILLIS) olmalıdır.
Geri çekilme politikası, sonraki yeniden deneme girişimleri için geri çekilme gecikmesinin zaman içinde nasıl artması gerektiğini tanımlar. WorkManager,
LINEAR
veEXPONENTIAL
olmak üzere 2 geri yükleme politikasını destekler.
Her çalışma isteğinin bir geri çekilme politikası ve geri çekilme gecikmesi vardır. Varsayılan politika, 30 saniyelik gecikmeyle EXPONENTIAL
'tür ancak bunu iş isteği yapılandırmanızda 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, her yeni denemeyle birlikte yeniden deneme aralığı yaklaşık 10 saniye artar. Örneğin, Result.retry()
ile biten ilk çalıştırma 10 saniye sonra tekrar denenir. Çalışma, sonraki denemelerden sonra Result.retry()
döndürmeye devam ederse 20, 30, 40 saniye vb. sonra tekrar denenir. Geri çekilme politikası EXPONENTIAL
olarak ayarlanmışsa yeniden deneme süresi sırası 20, 40, 80 vb. şeklinde olur.
Çalışmayı etiketleme
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 birbiriyle ilişkili bir iş grubunuz varsa bu iş öğelerini etiketlemeyi de yararlı bulabilirsiniz. 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. Bu etiketler dahili olarak bir dize dizisi olarak depolanır. WorkRequest
ile ilişkili etiket grubunu almak için WorkInfo.getTags() işlevini kullanabilirsiniz.
Worker
sınıfınızdaki etiket grubunu ListenableWorker.getTags() aracılığıyla alabilirsiniz.
Giriş verilerini atama
Çalışmanızın çalışması için giriş verileri gerekebilir. Örneğin, bir resmin yüklenmesini yöneten çalışma, yüklenecek resmin URI'sinin giriş olarak kullanılmasını gerektirebilir.
Giriş değerleri, Data
nesnesinde anahtar/değer çiftleri olarak depolanır ve çalışma isteğinde ayarlanabilir. WorkManager, işi yürüttüğünde Data
girişini işinize gönderir. Worker
sınıfı, Worker.getInputData()
'u çağırarak giriş bağımsız değişkenlerine erişebilir. Aşağıdaki kodda, giriş verisi gerektiren bir Worker
örneğinin nasıl oluşturulacağı ve bu örneğin iş isteğinizde nasıl gönderileceği gösterilmektedir.
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, döndürülen bir değer çıkışı için Data
sınıfı 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.