Worker
ve WorkRequest
tanımlarınızı belirledikten sonra son adım, çalışmanızı sıraya koymaktır. İşleri sıraya eklemenin en basit yolu, çalıştırmak istediğiniz WorkRequest
öğesini ileterek WorkManager enqueue()
yöntemini çağırmaktır.
Kotlin
val myWork: WorkRequest = // ... OneTime or PeriodicWork WorkManager.getInstance(requireContext()).enqueue(myWork)
Java
WorkRequest myWork = // ... OneTime or PeriodicWork WorkManager.getInstance(requireContext()).enqueue(myWork);
Yinelemeleri önlemek için çalışmaları sıraya eklerken dikkatli olun. Örneğin, bir uygulama 24 saatte bir günlüklerini bir arka uç hizmetine yüklemeyi deneyebilir. Dikkatli olmazsanız işin yalnızca bir kez çalıştırılması gerekse bile aynı görevi birçok kez kuyruğa alabilirsiniz. Bu hedefe ulaşmak için çalışmayı benzersiz çalışma olarak programlayabilirsiniz.
Benzersiz Çalışma
Benzersiz iş, belirli bir ad ile aynı anda yalnızca bir çalışma örneğinizin olduğunu garanti eden güçlü bir kavramdır. Kimliklerin aksine, benzersiz adlar kullanıcılar tarafından okunabilir ve WorkManager tarafından otomatik olarak oluşturulmak yerine geliştirici tarafından belirtilir. Etiketlerin aksine, benzersiz adlar yalnızca tek bir çalışma örneğiyle ilişkilendirilir.
Benzersiz çalışma, hem tek seferlik hem de dönemsel çalışmalara uygulanabilir. Tekrarlanan bir iş mi yoksa tek seferlik bir çalışma mı planladığınıza bağlı olarak bu yöntemlerden birini çağırarak benzersiz bir iş dizisi oluşturabilirsiniz.
- Tek seferlik iş için
WorkManager.enqueueUniqueWork()
- Periyodik çalışmalar için
WorkManager.enqueueUniquePeriodicWork()
Bu yöntemlerin her ikisi de 3 bağımsız değişkeni kabul eder:
- uniqueWorkName - İş isteğini benzersiz şekilde tanımlamak için kullanılan
String
. - existingWorkPolicy - Bu benzersiz ada sahip olan tamamlanmamış bir iş zinciri varsa WorkManager'a ne yapacağını bildiren bir
enum
. Daha fazla bilgi için çakışma çözümü politikasını inceleyin. - work - planlanacak
WorkRequest
.
Benzersiz çalışma kullanarak daha önce belirttiğimiz yinelenen planlama sorunumuzu çözebiliriz.
Kotlin
val sendLogsWorkRequest = PeriodicWorkRequestBuilder<SendLogsWorker>(24, TimeUnit.HOURS) .setConstraints(Constraints.Builder() .setRequiresCharging(true) .build() ) .build() WorkManager.getInstance(this).enqueueUniquePeriodicWork( "sendLogs", ExistingPeriodicWorkPolicy.KEEP, sendLogsWorkRequest )
Java
PeriodicWorkRequest sendLogsWorkRequest = new PeriodicWorkRequest.Builder(SendLogsWorker.class, 24, TimeUnit.HOURS) .setConstraints(new Constraints.Builder() .setRequiresCharging(true) .build() ) .build(); WorkManager.getInstance(this).enqueueUniquePeriodicWork( "sendLogs", ExistingPeriodicWorkPolicy.KEEP, sendLogsWorkRequest);
Artık bir sendLogs işi sıradayken kod çalışırsa mevcut iş korunur ve yeni iş eklenmez.
Benzersiz iş adım sıraları, aşamalı olarak uzun bir görev zinciri oluşturmanız gerektiğinde de yararlı olabilir. Örneğin, bir fotoğraf düzenleme uygulaması, kullanıcıların uzun bir işlem zincirini geri almalarına olanak tanıyabilir. Bu geri alma işlemlerinin her biri biraz zaman alabilir, ancak işlemlerin doğru sırayla gerçekleştirilmesi gerekir. Bu durumda, uygulama bir "geri al" zinciri oluşturabilir ve her geri alma işlemini gerektiği şekilde zincire ekleyebilir. Daha fazla bilgi için Zincirleme iş bölümünü inceleyin.
Çatışma çözümü politikası
Benzersiz çalışma planlarken, WorkManager'a bir çakışma olduğunda hangi işlemi gerçekleştireceğini bildirmeniz gerekir. Bunu işi sıraya alırken bir enum ileterek yaparsınız.
Tek seferlik çalışma için çakışmayı yönetmek için 4 seçeneği destekleyen bir ExistingWorkPolicy
sağlarsınız.
REPLACE
mevcut çalışmayı değiştirebilir. Bu seçenek mevcut çalışmayı iptal eder.KEEP
mevcut çalışmayı ve yeni çalışmayı yoksayabilirsiniz.APPEND
yeni çalışmayı mevcut çalışmanın sonuna aktarın. Bu politika, yeni çalışmanızın mevcut iş bittikten sonra çalıştırılacak şekilde mevcut çalışmaya zincirlenmesine neden olur.
Mevcut çalışma, yeni çalışmanın ön koşulu haline gelir. Mevcut çalışma CANCELLED
veya FAILED
haline gelirse yeni çalışma da CANCELLED
veya FAILED
olur.
Yeni çalışmanın, mevcut çalışmanın durumundan bağımsız olarak yayınlanmasını istiyorsanız bunun yerine APPEND_OR_REPLACE
işlevini kullanın.
APPEND_OR_REPLACE
,APPEND
işlevine benzer şekilde çalışır. Tek fark, ön koşul çalışma durumuna bağlı olmamasıdır. Mevcut çalışmaCANCELLED
veyaFAILED
ise yeni çalışma çalışmaya devam eder.
Dönem çalışması için REPLACE
ve KEEP
olmak üzere 2 seçeneği destekleyen bir ExistingPeriodicWorkPolicy
sağlarsınız. Bu seçenekler, MevcutWorkPolicy'ler
ile aynı şekilde çalışır.
Çalışmanızı gözlemleme
Çalışmayı sıraya aldıktan sonra herhangi bir noktada, WorkManager'ı name
, id
veya onunla ilişkilendirilmiş tag
kodu ile sorgulayarak durumunu kontrol edebilirsiniz.
Kotlin
// by id workManager.getWorkInfoById(syncWorker.id) // ListenableFuture<WorkInfo> // by name workManager.getWorkInfosForUniqueWork("sync") // ListenableFuture<List<WorkInfo>> // by tag workManager.getWorkInfosByTag("syncTag") // ListenableFuture<List<WorkInfo>>
Java
// by id workManager.getWorkInfoById(syncWorker.id); // ListenableFuture<WorkInfo> // by name workManager.getWorkInfosForUniqueWork("sync"); // ListenableFuture<List<WorkInfo>> // by tag workManager.getWorkInfosByTag("syncTag"); // ListenableFuture<List<WorkInfo>>
Sorgu, bir WorkInfo
nesnesinin ListenableFuture
bilgisini döndürür. İşin id
öğesi, etiketleri, mevcut State
ve Result.success(outputData)
aracılığıyla ayarlanan tüm çıkış verileri bu kapsamdadır.
Yöntemlerin her birinin LiveData
varyantı, bir işleyici kaydederek WorkInfo
öğesinde yapılan değişiklikleri gözlemlemenize olanak tanır. Örneğin, bazı işler başarıyla tamamlandığında kullanıcıya bir mesaj görüntülemek istiyorsanız bunu şu şekilde ayarlayabilirsiniz:
Kotlin
workManager.getWorkInfoByIdLiveData(syncWorker.id) .observe(viewLifecycleOwner) { workInfo -> if(workInfo?.state == WorkInfo.State.SUCCEEDED) { Snackbar.make(requireView(), R.string.work_completed, Snackbar.LENGTH_SHORT) .show() } }
Java
workManager.getWorkInfoByIdLiveData(syncWorker.id) .observe(getViewLifecycleOwner(), workInfo -> { if (workInfo.getState() != null && workInfo.getState() == WorkInfo.State.SUCCEEDED) { Snackbar.make(requireView(), R.string.work_completed, Snackbar.LENGTH_SHORT) .show(); } });
Karmaşık iş sorguları
WorkManager 2.4.0 ve sonraki sürümler, WorkQuery
nesnelerini kullanarak sıraya alınmış işler için karmaşık sorgulamaları destekler. WorkQuery, etiketleri, durumu ve benzersiz iş adı kombinasyonuna göre iş sorgulamayı destekler.
Aşağıdaki örnekte, FAILED
veya CANCELLED
durumundaki ve benzersiz bir iş adı olan "preProcess" ya da "sync" olan "syncTag" etiketiyle tüm çalışmaları nasıl bulabileceğiniz gösterilmektedir.
Kotlin
val workQuery = WorkQuery.Builder .fromTags(listOf("syncTag")) .addStates(listOf(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED)) .addUniqueWorkNames(listOf("preProcess", "sync") ) .build() val workInfos: ListenableFuture<List<WorkInfo>> = workManager.getWorkInfos(workQuery)
Java
WorkQuery workQuery = WorkQuery.Builder .fromTags(Arrays.asList("syncTag")) .addStates(Arrays.asList(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED)) .addUniqueWorkNames(Arrays.asList("preProcess", "sync") ) .build(); ListenableFuture<List<WorkInfo>> workInfos = workManager.getWorkInfos(workQuery);
WorkQuery
içindeki her bileşen (etiket, durum veya ad) diğerleriyle AND
-edilir. Bir bileşendeki her değer OR
-ed'dir. Örneğin: (name1 OR name2
OR ...) AND (tag1 OR tag2 OR ...) AND (state1 OR state2 OR ...)
.
WorkQuery
, LiveData eşdeğeri
getWorkInfosLiveData()
ile de çalışır.
İşleri iptal etme ve durdurma
Daha önce sıraya aldığınız çalışmanın artık yayınlanması için ihtiyacınız yoksa iptal edilmesini isteyebilirsiniz. İş, name
, id
veya onunla ilişkili bir tag
tarafından iptal edilebilir.
Kotlin
// by id workManager.cancelWorkById(syncWorker.id) // by name workManager.cancelUniqueWork("sync") // by tag workManager.cancelAllWorkByTag("syncTag")
Java
// by id workManager.cancelWorkById(syncWorker.id); // by name workManager.cancelUniqueWork("sync"); // by tag workManager.cancelAllWorkByTag("syncTag");
WorkManager, arka planda işin State
durumunu kontrol eder. İş bittiyse hiçbir şey olmaz. Aksi takdirde, çalışmanın durumu CANCELLED
olarak değiştirilir ve çalışma gelecekte çalışmaz. Bu işe bağlı olan tüm WorkRequest
işleri de CANCELLED
olacaktır.
Şu anda RUNNING
kullanıcıya ListenableWorker.onStopped()
çağrısı yapılıyor.
Olası temizleme işlemlerini işlemek için bu yöntemi geçersiz kılın. Daha fazla bilgi için çalışan bir çalışanı durdurma bölümüne bakın.
Çalışan bir Çalışanı durdurun
Worker
adlı çalıştırmanızın WorkManager tarafından durdurulmasının birkaç farklı nedeni olabilir:
- Açıkça iptal edilmesini istediniz (örneğin,
WorkManager.cancelWorkById(UUID)
numaralı telefonu arayarak). - Benzersiz çalışma söz konusu olduğunda, yeni bir
WorkRequest
öğesini açıkçaREPLACE
değeriExistingWorkPolicy
ile sıraya eklediniz. EskiWorkRequest
hemen iptal edilmiş olarak kabul edilir. - İşinizin kısıtlamaları artık karşılanmıyor.
- Sistem, uygulamanıza bir nedenle çalışmanızı durdurma talimatı verdi. Bu durum, son 10 dakikalık yürütme süresini aşarsanız gerçekleşebilir. Çalışmanın daha sonra yeniden denenmesi planlanır.
Bu koşullarda Çalışanınız durdurulur.
Devam etmekte olan tüm çalışmaları iş birliği içinde iptal etmeli ve Çalışanınızın elindeki kaynakları serbest bırakmalısınız. Örneğin, bu noktada veritabanlarına ve dosyalara açık tutamaçları kapatmanız gerekir. Çalışanınızın ne zaman durduğunu anlamak için kullanabileceğiniz iki mekanizma vardır.
onStopped() geri çağırması
WorkManager, Çalışan durdurulduğunda ListenableWorker.onStopped()
komutunu çağırır. Beklediğiniz kaynakları kapatmak için bu yöntemi geçersiz kılın.
isStopped() özelliği
Çalışanınızın durdurulup durdurulmadığını kontrol etmek için ListenableWorker.isStopped()
yöntemini çağırabilirsiniz. Çalışanınızda uzun süreli veya tekrarlanan işlemler gerçekleştiriyorsanız bu özelliği sık sık kontrol etmeli ve işi mümkün olan en kısa sürede durdurmak için sinyal olarak kullanmalısınız.
Not: WorkManager, onStop sinyalini alan bir Çalışan tarafından ayarlanan Result
özelliğini yok sayar. Bunun nedeni, Çalışanın zaten durdurulmuş kabul edilmesidir.