Memperbarui pekerjaan yang sudah ada dalam antrean

WorkManager memungkinkan Anda mengupdate WorkRequest setelah mengantrekannya. Hal ini sering kali diperlukan di aplikasi lebih besar yang sering mengubah batasan atau perlu mengupdate pekerjanya dengan cepat. Mulai WorkManager versi 2.8.0, updateWork() API merupakan cara untuk melakukannya.

Metode updateWork() memungkinkan Anda mengubah aspek tertentu dari WorkRequest dengan cepat, tanpa harus melalui proses pembatalan dan antrean yang baru secara manual. Hal ini sangat menyederhanakan proses pengembangan.

Menghindari pembatalan pekerjaan

Secara umum, Anda sebaiknya menghindari pembatalan WorkRequest yang ada dan mengantrekan WorkRequest baru. Hal itu dapat menyebabkan aplikasi mengulangi tugas tertentu, dan dapat mengharuskan Anda menulis kode tambahan dalam jumlah yang signifikan.

Pertimbangkan contoh berikut ketika pembatalan WorkRequest dapat menyebabkan kesulitan:

  • Permintaan backend: Jika Anda membatalkan Worker saat menghitung payload yang akan dikirim ke server, Worker baru harus memulai dari awal dan menghitung ulang payload yang berpotensi mahal.
  • Penjadwalan: Jika membatalkan PeriodicWorkRequest dan ingin PeriodicWorkRequest baru dieksekusi pada jadwal yang sama, Anda harus menghitung selisih waktu untuk memastikan bahwa waktu eksekusi baru sesuai dengan permintaan pekerjaan sebelumnya.

updateWork() API memungkinkan Anda memperbarui batasan permintaan pekerjaan dan parameter lainnya tanpa repot membatalkan dan mengantrekan permintaan baru.

Waktu untuk membatalkan pekerjaan

Ada kasus saat Anda harus langsung membatalkan WorkRequest, bukan memanggil updateWork(). Inilah yang harus Anda lakukan jika ingin mengubah sifat dasar pekerjaan yang telah diantrekan.

Waktu untuk memperbarui pekerjaan

Bayangkan jika ada aplikasi foto yang melakukan pencadangan foto pengguna setiap hari. Aplikasi telah mengantrekan PeriodicWorkRequest untuk melakukannya. WorkRequest memiliki batasan yang mengharuskan perangkat mengisi daya dan terhubung ke Wi-Fi.

Namun, pengguna hanya mengisi daya perangkatnya selama 20 menit sehari menggunakan pengisi daya cepat. Dalam hal ini, aplikasi mungkin ingin mengupdate WorkRequest untuk melonggarkan batasan pengisian daya, sehingga aplikasi masih dapat mengupload foto meskipun perangkat tidak terisi daya penuh.

Dalam situasi ini, Anda dapat menggunakan metode updateWork() untuk mengupdate batasan permintaan kerja.

Cara memperbarui pekerjaan

Metode updateWork() menyediakan cara sederhana untuk mengupdate WorkRequest yang sudah ada, tanpa harus membatalkan dan mengantrekan yang baru.

Untuk menggunakan update pekerjaan dalam antrean, ikuti langkah-langkah berikut:

  1. Mendapatkan ID yang ada untuk pekerjaan dalam antrean: Mendapatkan ID WorkRequest yang ingin diperbarui. Anda dapat mengambil ID ini dengan salah satu getWorkInfo API, atau dengan mempertahankan ID secara manual dari WorkRequest awal untuk pengambilan nanti dengan properti publik WorkRequest.id, sebelum mengantrekannya.
  2. Membuat WorkRequest baru: Buat WorkRequest baru dan gunakan WorkRequest.Builder.setID() untuk menetapkan ID-nya agar cocok dengan WorkRequest yang ada.
  3. Tetapkan batasan: Gunakan WorkRequest.Builder.setConstraints() untuk meneruskan batasan baru WorkManager.
  4. Panggilan updateWork: Meneruskan WorkRequest baru ke updateWork().

Perbarui contoh tugas

Berikut adalah contoh cuplikan kode di Kotlin yang menunjukkan cara menggunakan metode updateWork() untuk mengubah batasan baterai WorkRequest yang digunakan untuk mengupload foto:

suspend fun updatePhotoUploadWork() {
    // Get instance of WorkManager.
    val workManager = WorkManager.getInstance(context)

    // Retrieve the work request ID. In this example, the work being updated is unique
    // work so we can retrieve the ID using the unique work name.
    val photoUploadWorkInfoList = workManager.getWorkInfosForUniqueWork(
        PHOTO_UPLOAD_WORK_NAME
    ).await()

    val existingWorkRequestId = photoUploadWorkInfoList.firstOrNull()?.id ?: return

    // Update the constraints of the WorkRequest to not require a charging device.
    val newConstraints = Constraints.Builder()
        // Add other constraints as required here.
        .setRequiresCharging(false)
        .build()

    // Create new WorkRequest from existing Worker, new constraints, and the id of the old WorkRequest.
    val updatedWorkRequest: WorkRequest =
        OneTimeWorkRequestBuilder<MyWorker>()
            .setConstraints(newConstraints)
            .setId(existingWorkRequestId)
            .build()

    // Pass the new WorkRequest to updateWork().
    workManager.updateWork(updatedWorkRequest)
}

Menangani hasil

updateWork() akan menampilkan ListenableFuture<UpdateResult>. UpdateResult yang diberikan dapat memiliki salah satu dari beberapa nilai yang menguraikan apakah WorkManager dapat menerapkan perubahan Anda atau tidak. Hal ini juga menunjukkan kapan perubahan dapat diterapkan.

Untuk informasi selengkapnya, lihat referensi updateWork() dan UpdateResult .

Lacak pekerjaan dengan generasi

Setiap kali Anda mengupdate WorkRequest, generasinya akan bertambah satu. Hal ini memungkinkan Anda melacak dengan tepat WorkRequest mana yang saat ini diantrekan. Generasi memberi Anda lebih banyak kontrol saat mengamati, melacak, dan menguji permintaan tugas.

Untuk mendapatkan pembuatan WorkRequest, ikuti langkah-langkah berikut:

  1. WorkInfo: Panggil WorkManager.getWorkInfoById() untuk mengambil instance WorkInfo yang sesuai dengan WorkRequest Anda.
    • Anda dapat memanggil salah satu dari beberapa metode yang menampilkan WorkInfo. Untuk mengetahui informasi selengkapnya, lihat referensi WorkManager.
  2. getGeneration: Panggil getGeneration() pada instance WorkInfo. Int yang ditampilkan sesuai dengan pembuatan WorkRequest.
    • Perhatikan bahwa tidak ada kolom atau properti pembuatan, melainkan metode WorkInfo.getGeneration() saja.

Contoh pembuatan trek

Berikut adalah contoh implementasi alur kerja yang dijelaskan di atas untuk mengambil pembuatan WorkRequest.

// Get instance of WorkManager.
val workManager = WorkManager.getInstance(context)

// Retrieve WorkInfo instance.
val workInfo = workManager.getWorkInfoById(oldWorkRequestId)

// Call getGeneration to retrieve the generation.
val generation = workInfo.getGeneration()

Kebijakan untuk memperbarui pekerjaan

Sebelumnya, solusi yang direkomendasikan untuk memperbarui pekerjaan berkala adalah mengantrekan PeriodicWorkRequest dengan kebijakan ExistingPeriodicWorkPolicy.REPLACE. Jika ada PeriodicWorkRequest yang tertunda dengan id unik yang sama, permintaan kerja baru akan membatalkan dan menghapusnya. Kebijakan ini kini tidak digunakan lagi dan menggantikan alur kerja menggunakan ExistingPeriodicWorkPolicy.UPDATE.

Misalnya, saat menggunakan enqueueUniquePeriodicWork dengan PeriodicWorkRequest, Anda dapat menginisialisasi PeriodicWorkRequest baru dengan kebijakan ExistingPeriodicWorkPolicy.UPDATE. Jika ada PeriodicWorkRequest yang tertunda dengan nama unik yang sama, WorkManager akan mengupdatenya ke spesifikasi baru. Dengan mengikuti alur kerja ini, Anda tidak perlu menggunakan updateWork().