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.
Ş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
veEXPONENTIAL
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.