Başlangıç kılavuzunda, WorkRequest
oluşturma ve sıraya alma işlemi açıklanmıştır.
Bu kılavuzda, yaygın kullanım alanlarını ele almak için WorkRequest
nesnelerini nasıl tanımlayacağınızı ve özelleştireceğinizi öğreneceksiniz. Örneğin:
- Tek seferlik ve yinelenen işleri planlama
- Kablosuz bağlantı veya şarj gerektirme gibi çalışma kısıtlamaları ayarlama
- İş yürütmesinde minimum gecikme garantisi
- Yeniden deneme ve geri çekilme stratejilerini ayarlama
- Giriş verilerini işlemek için iletme
- İlgili çalışmaları etiketleri kullanarak gruplandırma
Genel Bakış
WorkManager'da iş, WorkRequest
kullanılarak tanımlanır. WorkManager ile herhangi bir iş planlamak için önce bir WorkRequest
nesnesi oluşturup ardından bunu 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 planlayıp ç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 tekrarlanan aralıklar gibi planlama bilgilerini, yeniden deneme yapılandırmasını içerir ve çalışmanız buna bağlıysa giriş verilerini içerebilir.
WorkRequest
kendisi 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, PeriodicWorkRequest
ise belirli aralıklarla tekrarlanan işleri planlamak için daha uygundur.
Tek seferlik işleri planlama
Ek yapılandırma gerektirmeyen temel işlemler 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 çalışmalar 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 üzerinde daha iyi kontrol sağlar.
Yüksek öncelikli işler aşağıdaki özellikleriyle 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 seçenektir.
- 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ışmayı etkileme olasılığı daha düşüktür.
- Gecikme: Sistem, mevcut iş yükünün buna izin vermesi koşuluyla hızlandırılmış işi hemen yürütür. Bu, işlerin gecikmeye duyarlı olduğu ve daha sonra yürütülmek üzere planlanamayacağı anlamına gelir.
Hızlı çalışma için olası bir kullanım alanı, kullanıcının mesaj veya ekli resim göndermek istediği bir sohbet uygulaması olabilir. Benzer şekilde, ödeme veya abonelik akışını işleyen bir uygulama da hızlandırılmış çalışmayı 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ı ve kullanıcı uygulamayı kapatsa bile yürütülmeye devam etmesi gerektiğidir.
Kotalar
Sistemin, hızlandırılmış bir işin çalışabilmesi için yürütme süresi ayırması gerekir. Yürütme süresi sınırsız değildir. Bunun yerine, her uygulama için bir yürütme süresi kotası belirlenir. Uygulamanız yürütme süresini kullandığında ve ayrılan kotasına ulaştığında, kota yenilenene kadar artık hızlandırılmış iş yürütemezsiniz. Bu sayede Android, uygulamalar arasındaki kaynakları daha etkili bir şekilde dengeleyebilir.
Bir uygulamanın kullanabileceği yürütme süresi, bekleme paketine ve işlem önemine göre belirlenir.
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, setExpedited()
işinin hızlandırılmış bir iş kullanılarak mümkün olduğunca hızlı çalışması gerektiğini bildirmek için WorkRequest
işini çağırabilir. Aşağıdaki kod snippet'i, setExpedited()
öğesinin nasıl kullanılacağına dair bir örnek sunmaktadır:
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, OneTimeWorkRequest
sınıfının bir örneğini başlatıp üzerinde setExpedited()
yöntemini çağırıyoruz. Bu istek daha sonra 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, hızlandırılmamış bir işlem olarak çalıştırılması gerektiğini belirtir.
Geriye dönük uyumluluk ve ön plan hizmetleri
Hızlandırılmış işlerde geriye dönük uyumluluğu korumak için WorkManager, Android 12'den eski platform sürümlerinde ön plan hizmeti çalıştırabilir. Ön plan hizmetleri, kullanıcıya bildirim gösterebilir.
Worker'ınızdaki getForegroundInfoAsync()
ve getForegroundInfo()
yöntemleri, Android 12'den önceki sürümlerde setExpedited()
'ı çağırdığınızda WorkManager'ın bildirim göstermesini sağlar.
Görevlerin hızlandırılmış iş olarak çalıştırılmasını istiyorsanız tüm ListenableWorker
, getForegroundInfo
yöntemini uygulamalıdır.
Android 12 veya sonraki sürümler hedeflenirken ön plan hizmetleri, ilgili setForeground
yöntemiyle kullanılabilir.
Çalışan
Çalışanlar, yaptıkları işin hızlandırılmış olup olmadığını bilmiyor. Ancak çalışanlar, WorkRequest
hızlandırıldığında Android'in bazı sürümlerinde bildirim gösterebilir.
Bunu etkinleştirmek için WorkManager, getForegroundInfoAsync()
yöntemini sağlar. WorkManager'ın gerektiğinde sizin için bir ForegroundService
başlatmak üzere bildirim gösterebilmesi için bu yöntemi uygulamanız gerekir.
CoroutineWorker
CoroutineWorker
kullanıyorsanız getForegroundInfo()
'yi uygulamanız gerekir. Daha sonra doWork()
içinde setForeground()
'ya iletirsiniz. Bu işlem, Android 12'den önceki sürümlerde bildirimi oluşturur.
Aşağıdaki örneği inceleyelim:
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şlerin ne olacağını kontrol edebilirsiniz. Devam etmek için setExpedited()
sınavını geçebilirsiniz:
OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST
, bu da işin normal bir iş isteği olarak çalışmasına neden olur. Önceki snippet bunu gösteriyor.OutOfQuotaPolicy.DROP_WORK_REQUEST
, bu da yeterli kota olmaması durumunda isteğin iptal edilmesine neden olur.
Ertelenen yüksek öncelikli iş
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 gibi durumlarda yeni hızlandırılmış işlerin başlangıcını erteleyebilir:
- Yük: Sistem yükü çok yüksek. Bu durum, çok fazla iş zaten çalışırken 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 kayan bir zaman aralığındaki maksimum yürütme süresini sınırlar. Hızlandırılmış iş 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 çalışma planlama
Uygulamanızın zaman zaman belirli işlemlerin düzenli olarak çalışmasını gerektirmesi mümkündür. Örneğin, verilerinizi düzenli olarak yedeklemek, uygulamanıza yeni içerikler indirmek veya günlükleri bir sunucuya yüklemek isteyebilirsiniz.
Periyodik olarak yürütülen bir PeriodicWorkRequest
oluşturmak için WorkRequest
nesnesini ş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 saat aralıklarla planlanmıştır.
Aralık süresi, tekrarlar arasındaki minimum süre olarak tanımlanır. Çalışanın tam olarak ne zaman yürütüleceği, 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ı
İşinizin doğası, zamanlamaya duyarlı olmanızı gerektiriyorsa Şekil 1'de gösterildiği gibi PeriodicWorkRequest
'nizi her aralık döneminde esnek bir dönem içinde çalışacak şekilde yapılandırabilirsiniz.
1.şekil Şemada, işin yürütülebileceği esnek dönemle birlikte yinelenen aralıklar gösterilmektedir.
Esnek dönem içeren periyodik çalışma tanımlamak için flexInterval
oluştururken PeriodicWorkRequest
ile birlikte repeatInterval
değerini iletirsiniz. Esneklik dönemi repeatInterval - flexInterval
'da başlar ve aralığın sonuna kadar devam eder.
Aşağıda, her saatlik dönemin son 15 dakikasında çalıştırılabilen periyodik bir iş ö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
değerine eşit veya bu değerden büyük olmalı, esnek aralık ise PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS` değerine eşit veya bu değerden büyük olmalıdır.
Kısıtlamaların Periyodik Çalışma Üzerindeki Etkisi
Periyodik çalışmalara 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 bu koşul karşılanana kadar PeriodicWorkRequest
çalıştırılmaz. Bu durum, çalışmanızın belirli bir çalıştırma işleminin gecikmesine veya koşullar çalıştırma aralığında karşılanmazsa atlanmasına bile neden olabilir.
Çalışma kısıtlamaları
Constraints
Çalışmanın, en uygun koşullar sağlanana kadar ertelenmesini sağlar. WorkManager için aşağıdaki kısıtlamalar kullanılabilir:
NetworkType | Çalışmanızın yürütülmesi 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 işiniz yalnızca cihaz şarj olurken çalışır. |
DeviceIdle | Doğru olarak ayarlandığında, işin çalıştırılabilmesi için kullanıcının cihazının boşta olması gerekir. Bu, aksi takdirde kullanıcının cihazında etkin olarak çalışan diğer uygulamalar üzerinde olumsuz bir performans etkisi yaratabilecek toplu işlemleri çalıştırmak için yararlı olabilir. |
StorageNotLow | Doğru olarak ayarlandığında, kullanıcının cihazındaki depolama alanı çok düşükse çalışmanız yürütülmez. |
Bir dizi kısıtlama oluşturup bunları bir işle ilişkilendirmek için Constraints.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 bağlantıya 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 yürütülürken bir kısıtlama karşılanmazsa WorkManager, çalışanınızı durdurur. Tüm kısıtlamalar karşılandığında iş yeniden denenir.
Gecikmeli Çalışma
Çalışmanızda kısıtlama yoksa veya çalışmanız sıraya alındığında tüm kısıtlamalar karşılanıyorsa sistem, çalışmayı hemen çalıştırmayı seçebilir. Çalışmanın hemen yürütülmesini istemiyorsanız çalışmanızın minimum başlangıç gecikmesinden sonra başlamasını belirtebilirsiniz.
Çalışmanızın, sıraya alındıktan en az 10 dakika sonra çalışacak şekilde nasıl ayarlanacağına 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, bir OneTimeWorkRequest
için ilk gecikmenin nasıl ayarlanacağı gösterilse de bir PeriodicWorkRequest
için de ilk gecikme ayarlayabilirsiniz. Bu durumda, yalnızca periyodik çalışmanızın ilk çalıştırması gecikir.
Yeniden deneme ve geri çekilme politikası
WorkManager'ın çalışmanızı yeniden denemesini istiyorsanız işçinizden Result.retry()
değerini döndürebilirsiniz. Çalışmanız daha sonra geri çekilme gecikmesi ve geri çekilme politikasına göre yeniden planlanır.
Geri yükleme aralığı, ilk denemeden sonra çalışmanızı yeniden denemeden önce beklemeniz gereken minimum süreyi belirtir. Bu değer 10 saniyeden (veya MIN_BACKOFF_MILLIS) az olamaz.
Geri çekilme politikası, sonraki yeniden deneme girişimlerinde geri çekilme gecikmesinin zaman içinde nasıl artacağını tanımlar. WorkManager, 2 geri çekilme politikasını destekler:
LINEAR
veEXPONENTIAL
.
Her iş isteğinin bir geri çekilme politikası ve geri çekilme gecikmesi vardır. Varsayılan politika, 30 saniyelik gecikmeyle EXPONENTIAL
şeklindedir ancak bu ayarı iş isteği yapılandırmanızda geçersiz kılabilirsiniz.
Aşağıda, geri çekilme gecikmesinin 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 aralığı, izin verilen minimum değer olan 10 saniyeye ayarlanmıştır. Politika LINEAR
olduğundan, yeniden deneme aralığı her yeni denemede yaklaşık 10 saniye artar. Örneğin, Result.retry()
ile biten ilk çalıştırma 10 saniye sonra tekrar denenir. İş sonraki denemelerde de Result.retry()
döndürmeye devam ederse 20, 30, 40 vb. saniye sonra tekrar denenir. Geri çekilme politikası EXPONENTIAL
olarak ayarlanırsa yeniden deneme süresi sırası 20, 40 ve 80'e daha yakın olur.
Çalışma etiketleme
Her iş isteğinin benzersiz bir tanımlayıcısı vardır. Bu tanımlayıcı, işi daha sonra tanımlamak, iptal etmek veya ilerleme durumunu gözlemlemek için kullanılabilir.
Mantıksal olarak ilişkili bir iş grubunuz varsa bu iş öğelerini etiketlemek de faydalı 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 iş durumunu belirlemek için kullanılabilecek WorkInfo nesnelerinin listesini döndürür.
Aşağıdaki kod, çalışmanıza 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. Dahili olarak bu etiketler bir dizi dize olarak depolanır. WorkRequest
ile ilişkili etiket grubunu almak için WorkInfo.getTags()
kullanabilirsiniz.
Worker
sınıfınızdan, ListenableWorker.getTags() kullanarak etiket grubunu alabilirsiniz.
Giriş verilerini atama
İşiniz için giriş verileri gerekebilir. Örneğin, bir resmi yüklemeyi işleyen bir işlem için giriş olarak yüklenecek resmin URI'si gerekebilir.
Giriş değerleri, Data
nesnesinde anahtar/değer çiftleri olarak saklanır ve iş isteğinde ayarlanabilir. WorkManager, çalışmayı yürüttüğünde Data
girişini çalışmanıza iletir. Worker
sınıfı, Worker.getInputData()
'ı çağırarak giriş bağımsız değişkenlerine erişebilir. Aşağıdaki kodda, giriş verileri gerektiren bir Worker
örneğini nasıl oluşturabileceğiniz ve bunu 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, 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ınmaktadır.
Sonraki Adımlar
Durumlar ve gözlem sayfasında, iş durumları ve işinizin ilerleme durumunu nasıl izleyeceğiniz hakkında daha fazla bilgi edinebilirsiniz.