Setelah Anda menentukan
Worker
dan
WorkRequest
,
maka langkah terakhir adalah mengantrekan pekerjaan. Cara termudah untuk mengantrekan pekerjaan
adalah dengan memanggil metode WorkManager enqueue()
, yakni dengan meneruskan WorkRequest
yang ingin dijalankan.
Kotlin
val myWork: WorkRequest = // ... OneTime or PeriodicWork WorkManager.getInstance(requireContext()).enqueue(myWork)
Java
WorkRequest myWork = // ... OneTime or PeriodicWork WorkManager.getInstance(requireContext()).enqueue(myWork);
Berhati-hatilah saat mengantrekan pekerjaan untuk menghindari duplikasi. Misalnya, sebuah aplikasi mungkin akan mencoba mengupload log ke layanan backend setiap 24 jam. Jika tidak berhati-hati, Anda mungkin akan mengantrekan tugas yang sama berkali-kali, meskipun pekerjaan hanya perlu dijalankan sekali. Untuk mencapai tujuan ini, Anda dapat menjadwalkannya sebagai pekerjaan unik.
Pekerjaan Unik
Pekerjaan unik merupakan konsep ampuh yang akan menjamin bahwa Anda hanya memiliki satu instance pekerjaan dengan nama tertentu pada satu waktu. Tidak seperti ID, nama unik dapat dibaca oleh manusia dan ditentukan oleh developer, bukan dibuat secara otomatis oleh WorkManager. Tidak seperti tag, nama unik hanya dikaitkan dengan satu instance pekerjaan.
Pekerjaan unik dapat diterapkan baik untuk pekerjaan satu kali maupun pekerjaan berkala. Anda dapat membuat urutan kerja yang unik dengan memanggil salah satu metode ini, bergantung pada apakah Anda menjadwalkan pekerjaan berulang atau pekerjaan satu kali.
WorkManager.enqueueUniqueWork()
untuk pekerjaan satu kaliWorkManager.enqueueUniquePeriodicWork()
untuk pekerjaan berkala
Kedua metode ini menerima 3 argumen:
- uniqueWorkName - Sebuah
String
yang digunakan untuk mengidentifikasi permintaan kerja secara unik. - existingWorkPolicy - Sebuah
enum
yang akan memberi tahu WorkManager tindakan yang harus dilakukan jika sudah ada rantai pekerjaan dengan nama unik tersebut yang belum selesai. Lihat kebijakan resolusi konflik untuk informasi selengkapnya. - work - Ini adalah
WorkRequest
yang akan dijadwalkan.
Dengan menggunakan pekerjaan unik, kita bisa memperbaiki masalah penjadwalan duplikat yang telah diketahui sebelumnya.
Kotlin
val sendLogsWorkRequest = PeriodicWorkRequestBuilderS<endLogsWorker(>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);
Kini, jika kode berjalan saat pekerjaan sendLogs sudah berada dalam antrean, pekerjaan yang ada akan disimpan dan tidak ada pekerjaan baru yang ditambahkan.
Urutan pekerjaan unik juga dapat digunakan jika Anda perlu membuat rantai tugas yang panjang secara bertahap. Misalnya, aplikasi pengeditan foto dapat memungkinkan pengguna untuk mengurungkan rantai tindakan yang panjang. Setiap operasi urungkan mungkin perlu waktu beberapa saat, tetapi harus dilakukan dengan urutan yang benar. Dalam hal ini, aplikasi dapat membuat rantai "urungkan" dan menambahkan setiap operasi urungkan ke rantai tersebut sesuai kebutuhan. Lihat Perantaian pekerjaan untuk detail selengkapnya.
Kebijakan resolusi konflik
Saat menjadwalkan pekerjaan unik, Anda harus memberi tahu WorkManager tindakan yang harus diambil saat terjadi konflik. Tindakan ini dapat dilakukan dengan meneruskan enum saat mengantrekan pekerjaan.
Untuk pekerjaan satu kali, Anda perlu menyediakan
ExistingWorkPolicy
, yang
mendukung 4 opsi untuk menangani konflik.
REPLACE
pekerjaan yang sudah ada dengan pekerjaan baru. Opsi ini membatalkan pekerjaan yang ada.KEEP
pekerjaan yang ada dan mengabaikan pekerjaan baru.APPEND
pekerjaan baru hingga akhir pekerjaan yang ada. Kebijakan ini akan menyebabkan pekerjaan baru Anda dirantai ke pekerjaan yang ada, dan dijalankan setelah pekerjaan tersebut selesai.
Pekerjaan yang ada akan menjadi prasyarat untuk pekerjaan baru. Jika pekerjaan yang ada
menjadi CANCELLED
atau FAILED
, pekerjaan baru juga akan menjadi CANCELLED
atau FAILED
.
Jika Anda ingin menjalankan pekerjaan baru, terlepas dari status pekerjaan yang sudah ada,
gunakan APPEND_OR_REPLACE
.
APPEND_OR_REPLACE
berfungsi serupa denganAPPEND
, tetapi itu tidak bergantung pada status kerja prasyarat. Jika pekerjaan yang ada memiliki statusCANCELLED
atauFAILED
, pekerjaan baru akan tetap berjalan.
Untuk pekerjaan berkala, Anda perlu menyediakan
ExistingPeriodicWorkPolicy
,
yang mendukung 2 opsi, yaitu REPLACE
dan KEEP
. Opsi ini memiliki fungsi yang sama
dengan pasangan ExistingWorkPolicy.
Mengamati pekerjaan
Kapan pun setelah mengantrekan pekerjaan, Anda dapat memeriksa statusnya dengan mengajukan kueri
WorkManager berdasarkan name
, id
, atau dengan tag
yang terkait dengannya.
Kotlin
// by id workManager.getWorkInfoById(syncWorker.id) // ListenableFutureW<orkInfo<>/span> // by name workManager.getWorkInfosForUniqueWork("sync") // ListenableFutureL<istW<orkInfo<>/span> > // by tag workManager.getWorkInfosByTag("syncTag") // ListenableFutureL<istW<orkInfo<>/span> >
Java
// by id workManager.getWorkInfoById(syncWorker.id); // ListenableFutureW<orkInfo<>/span> // by name workManager.getWorkInfosForUniqueWork("sync"); // ListenableFutureL<istW<orkInfo<>/span> > // by tag workManager.getWorkInfosByTag("syncTag"); // ListenableFutureL<istW<orkInfo<>/span> >
Kueri tersebut menampilkan ListenableFuture
dari sebuah objek WorkInfo
, yang mencakup id
pekerjaan, tag-nya, State
-nya saat ini, dan semua data output yang disetel melalui Result.success(outputData)
.
Varian LiveData
untuk setiap metode
memungkinkan Anda mengamati perubahan WorkInfo
dengan mendaftarkan
pemroses. Misalnya, jika ingin menampilkan pesan kepada pengguna saat
beberapa pekerjaan berhasil diselesaikan, Anda dapat mengaturnya sebagai berikut:
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(); } });
Kueri pekerjaan yang kompleks
WorkManager 2.4.0 dan yang lebih tinggi mendukung kueri yang kompleks untuk pekerjaan yang diantrekan menggunakan objek
WorkQuery
. WorkQuery mendukung
proses pembuatan kueri untuk pekerjaan dari kombinasi tag, status, dan nama pekerjaan unik.
Contoh berikut ini menunjukkan cara untuk menemukan semua pekerjaan yang berisi tag, “syncTag”, yang memiliki status FAILED
maupun CANCELLED
dan memiliki nama kerja yang unik untuk "preProcess” atau “sync”.
Kotlin
val workQuery = WorkQuery.Builder .fromTags(listOf("syncTag")) .addStates(listOf(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED)) .addUniqueWorkNames(listOf("preProcess", "sync") ) .build() val workInfos: ListenableFutureL<istW<orkInfo >>= 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(); ListenableFutureL<istW<orkInfo >>workInfos = workManager.getWorkInfos(workQuery);
Setiap komponen (tag, status, atau nama) pada WorkQuery
akan diberi AND
seperti komponen lainnya. Setiap nilai dalam komponen akan diberi OR
. Misalnya: (name1 OR name2
OR ...) AND (tag1 OR tag2 OR ...) AND (state1 OR state2 OR ...)
.
WorkQuery
juga berfungsi dengan LiveData yang setara,
getWorkInfosLiveData()
.
Membatalkan dan menghentikan pekerjaan
Jika sudah tidak perlu pekerjaan yang sebelumnya diantrekan, Anda dapat meminta
untuk membatalkan pekerjaan tersebut. Pekerjaan dapat dibatalkan oleh name
, id
, atau tag
yang terkait dengannya.
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");
Di balik layar, WorkManager memeriksa
State
pekerjaan. Jika pekerjaan
sudah selesai,
tidak ada yang terjadi. Jika tidak, status pekerjaan diubah menjadi
CANCELLED
dan pekerjaan
tidak akan dijalankan lagi di masa mendatang. Semua
pekerjaan WorkRequest
yang bergantung
pada pekerjaan ini juga
akan menjadi CANCELLED
.
Saat ini pekerjaan RUNNING
menerima panggilan ke ListenableWorker.onStopped()
.
Ganti metode ini untuk menangani segala potensi pembersihan. Lihat menghentikan
pekerja yang berjalan untuk informasi selengkapnya.
Menghentikan Worker yang sedang berjalan
Ada beberapa alasan mengapa Worker
yang sedang berjalan mungkin dihentikan oleh WorkManager:
- Anda secara eksplisit memintanya untuk dibatalkan (misalnya dengan memanggil
WorkManager.cancelWorkById(UUID)
). - Untuk pekerjaan unik,
Anda secara eksplisit mengantrekan
WorkRequest
baru denganExistingWorkPolicy
dariREPLACE
.WorkRequest
lama langsung dianggap dibatalkan. - Batasan pekerjaan Anda tidak lagi terpenuhi.
- Sistem menginstruksikan aplikasi agar menghentikan pekerjaan karena suatu alasan. Hal ini dapat terjadi jika Anda melebihi batas waktu eksekusi selama 10 menit. Pekerjaan akan dijadwalkan untuk dicoba lagi nanti.
Worker akan dihentikan dalam kondisi seperti ini.
Jika demikian, Anda harus mau membatalkan pekerjaan apa pun yang sedang dilakukan dan melepaskan semua resource berisi Worker. Sebagai contoh, dalam situasi ini, Anda harus menutup proses penanganan database dan file yang masih terbuka. Anda dapat menggunakan dua mekanisme untuk mengetahui kapan Worker akan berhenti bekerja.
Callback onStopped()
WorkManager memanggil ListenableWorker.onStopped()
segera setelah Worker dihentikan. Ganti metode ini untuk menutup
resource yang mungkin Anda miliki.
Properti isStopped()
Anda dapat memanggil metode
ListenableWorker.isStopped()
untuk memeriksa apakah pekerja sudah dihentikan. Jika Anda menjalankan operasi dalam waktu lama atau berulang di dalam Worker, Anda harus sering memeriksa properti ini dan menggunakannya sebagai sinyal untuk menghentikan pekerjaan sesegera mungkin.
Catatan: WorkManager mengabaikan
Result
yang ditetapkan oleh Worker yang telah menerima sinyal onStop, karena Worker sudah dianggap berhenti.