Başlarken kılavuzunda, WorkRequest
oluşturma ve sıraya ekleme işlemleri ele alınmıştır.
Bu kılavuzda, yaygın kullanım alanlarını (ör. aşağıdakiler) ele almak için WorkRequest
nesnelerini nasıl tanımlayacağınızı ve özelleştireceğinizi öğreneceksiniz:
- Tek seferlik ve yinelenen işleri planlama
- 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ış
WorkManager'da iş, WorkRequest
kullanılarak tanımlanır. WorkManager ile herhangi bir işi planlamak için önce bir WorkRequest
nesnesi oluşturmanız, 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. İsteği oluşturmak için kullanabileceğiniz bu sınıfın 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 temel çalışmalar için statik yöntem 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 Uyku modu gibi güç yönetimi kısıtlamalarının hızlandırılmış çalışmaları etkileme olasılığı 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ı bir şekilde yürütülmesi, hemen başlatılması ve kullanıcı uygulamayı kapatsa bile yürütülmeye devam etmesidir.
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>()
<b>.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)</b>
.build()
WorkManager.getInstance(context)
.enqueue(request)
Java
OneTimeWorkRequest request = new OneTimeWorkRequestBuilder<T>()
.setInputData(inputData)
<b>.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)</b>
.build();
Bu örnekte, bir OneTimeWorkRequest
örneğini başlatıp üzerinde setExpedited()
işlevini çağırıyoruz. Bu istek, 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 şekilde, hızlandırılmamış çalışma olarak çalıştırılması gerektiğini belirtir.
Geriye dönük uyumluluk ve ön plan hizmetleri
WorkManager, hızlandırılmış işler için geriye dönük uyumluluğu korumak amacıyla Android 12'den eski platform sürümlerinde ö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ı bilmez. Ancak WorkRequest
hızlandırıldığında, çalışanlar Android'in bazı sürümlerinde bildirim gösterebilir.
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.
CoroutineWorker
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()
değerini iletebilirsiniz:
OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST
, bu da işin sıradan bir iş isteği olarak çalışmasına neden olur. Önceki snippet'te bu gösterilmektedir.OutOfQuotaPolicy.DROP_WORK_REQUEST
, yeterli kota yoksa isteğin iptal edilmesine neden olur.
Ertelenen yüksek öncelikli iş
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 çalışan bir WorkRequest
nesnesi oluşturmak için PeriodicWorkRequest
öğesini aşağıdaki şekilde kullanırsınız:
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
'inizi, Şekil 1'de gösterildiği gibi her aralık dönemindeki 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ık 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 yalnızca kullanıcının cihazı şarj olurken çalışacak ş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şılanmadığı takdirde atlanmasına neden olabilir.
Çalışma kısıtlamaları
Constraints
En uygun koşullar sağlanana kadar çalışmanın ertelendiğinden emin olun. WorkManager aşağıdaki kısıtlamaları kullanabilir:
NetworkType | Çalışmanızın çalıştırılması için gereken ağ türünü kısıtlar.
Örneğin, kablosuz (UNMETERED ).
|
BatteryNotLow | Doğru olarak ayarlandığında, cihaz düşük pil modundaysa çalışmanız çalışmaz. |
RequiresCharging | Doğru olarak ayarlandığında, çalışmanız yalnızca cihaz şarj olurken çalışır. |
DeviceIdle | True (doğru) değerine ayarlandığında, çalışmanın çalıştırılması 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 performans etkisi olabilecek toplu işlemleri çalıştırmak için yararlı olabilir. |
StorageNotLow | Doğru olarak ayarlandığında, kullanıcının cihazdaki depolama alanı çok düşükse çalışmanız çalışmaz. |
Bir dizi kısıtlama oluşturmak ve bu kısıtlamaları bir çalışmayla ilişkilendirmek için Constraints.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 oluyor hem de kablosuz ağa bağlıyken ç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, işleyicinizi durdurur. Tüm kısıtlamalar karşılandığında çalışma yeniden denenir.
Gecikmeli Çalışma
Çalışmanızda herhangi bir kısıtlama yoksa veya çalışmanız sıraya eklendiğinde tüm kısıtlamalar karşılanıyorsa sistem, çalışmayı hemen çalıştırmayı seçebilir. Çalışmanın hemen yayınlanmasını istemiyorsanız minimum bir başlangıç gecikmesinden sonra başlaması için çalışmanızı 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 çekilme politikası
WorkManager'ın çalışmanızı yeniden denemesini istiyorsanız işleyicinizden Result.retry()
döndürebilirsiniz. Ardından, çalışmanız geri çekilme gecikmesine ve geri çekilme 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 çekilme politikasını destekler.
Her çalışma isteği için 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 çekilme gecikmesi ve politikasının özelleştirilmesine ilişkin 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 ve 80'e daha yakın olur.
Çalışmayı etiketleme
Her iş isteği, iptal etmek veya ilerleme durumunu gözlemlemek için daha sonra bu işi tanımlamak üzere kullanılabilecek bir benzersiz tanımlayıcıya sahiptir.
Mantıksal olarak birbiriyle ilişkili bir iş grubunuz varsa bu iş öğelerini etiketlemeyi de faydalı 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 iş durumunu belirlemek için kullanılabilecek WorkInfo nesnelerinin listesini döndürür.
Aşağıdaki kod, çalışmanıza nasıl "temizlik" etiketi ekleyeceğ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()
kullanabilirsiniz.
Worker
sınıfınızda, ListenableWorker.getTags() yöntemini kullanarak sınıfın etiket grubunu alabilirsiniz.
Giriş verilerini atama
Çalışmanızın çalışması için giriş verileri gerekebilir. Örneğin, bir resmin yüklenmesini yöneten çalışmada, resmin URI'sinin giriş olarak yüklenmesi gerekebilir.
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()
'yi çağırarak giriş bağımsız değişkenlerine erişebilir. Aşağıdaki kodda, giriş verisi gerektiren bir Worker
örneğini nasıl oluşturabileceğiniz ve bu örneği iş isteğinizde nasıl gönderebileceğiniz 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özlem sayfasında, çalışma durumları ve çalışmanızın ilerleme durumunu nasıl izleyeceğiniz hakkında daha fazla bilgi edinebilirsiniz.