WorkManager memudahkan penyiapan dan penjadwalan permintaan tugas yang rumit. Anda dapat menggunakan API untuk skenario seperti ini:
- Urutan berantai dari tugas yang berjalan dalam urutan yang telah ditentukan
- Urutan bernama unik, dengan aturan untuk apa yang akan terjadi jika aplikasi meluncurkan dua urutan dengan nama yang sama
- Tugas yang meneruskan dan menampilkan nilai, termasuk tugas berantai yang mana setiap tugas meneruskan argumen ke tugas berikutnya dalam rantai tersebut
Tugas berantai
Aplikasi Anda mungkin perlu menjalankan beberapa tugas dalam urutan tertentu.
WorkManager
memungkinkan Anda membuat dan mengantrekan urutan pekerjaan yang
menentukan beberapa tugas, serta menetapkan urutan berjalannya tugas tersebut.
Misalnya, aplikasi Anda memiliki tiga objek
OneTimeWorkRequest
: workA
, workB
, dan
workC
. Tugas harus dijalankan dalam urutan tersebut. Untuk mengantrekannya, buat urutan
dengan metode
WorkManager.beginWith(OneTimeWorkRequest)
,
yang meneruskan objek OneTimeWorkRequest
pertama;
metode tersebut menampilkan objek WorkContinuation
, yang
menentukan urutan tugas. Kemudian, tambahkan
objek OneTimeWorkRequest
lainnya, sesuai urutan, dengan
WorkContinuation.then(OneTimeWorkRequest)
, dan
terakhir, antrekan semua urutan tersebut dengan
WorkContinuation.enqueue()
:
Kotlin
WorkManager.getInstance(myContext) .beginWith(workA) // Note: WorkManager.beginWith() returns a // WorkContinuation object; the following calls are // to WorkContinuation methods .then(workB) // FYI, then() returns a new WorkContinuation instance .then(workC) .enqueue()
Java
WorkManager.getInstance(myContext) .beginWith(workA) // Note: WorkManager.beginWith() returns a // WorkContinuation object; the following calls are // to WorkContinuation methods .then(workB) // FYI, then() returns a new WorkContinuation instance .then(workC) .enqueue();
WorkManager
menjalankan tugas dalam urutan yang diminta,
sesuai dengan batasan setiap tugas yang telah ditentukan. Jika tugas apa pun menampilkan
Result.failure()
,
seluruh urutan akan berakhir.
Anda juga dapat meneruskan beberapa objek OneTimeWorkRequest
ke salah satu panggilan
beginWith(List<OneTimeWorkRequest>)
dan
then(List<OneTimeWorkRequest>)
. Jika Anda meneruskan beberapa
objek OneTimeWorkRequest
ke satu panggilan
metode, WorkManager
menjalankan semua tugas tersebut (secara paralel)
sebelum menjalankan sisa urutannya. Contoh:
Kotlin
WorkManager.getInstance(myContext) // First, run all the A tasks (in parallel): .beginWith(Arrays.asList(workA1, workA2, workA3)) // ...when all A tasks are finished, run the single B task: .then(workB) // ...then run the C tasks (in parallel): .then(Arrays.asList(workC1, workC2)) .enqueue()
Java
WorkManager.getInstance(myContext) // First, run all the A tasks (in parallel): .beginWith(Arrays.asList(workA1, workA2, workA3)) // ...when all A tasks are finished, run the single B task: .then(workB) // ...then run the C tasks (in parallel): .then(Arrays.asList(workC1, workC2)) .enqueue();
Anda dapat membuat urutan yang lebih kompleks dengan menggabungkan beberapa rantai menggunakan metode WorkContinuation.combine(List<OneTimeWorkRequest>)
. Misalnya, Anda ingin menjalankan urutan seperti ini:
WorkContinuation
untuk menyiapkan tugas berantai yang kompleks.
Untuk menyiapkan urutan ini, buat dua rantai yang berbeda, lalu gabungkan rantai tersebut menjadi rantai ketiga:
Kotlin
val chain1 = WorkManager.getInstance(myContext) .beginWith(workA) .then(workB) val chain2 = WorkManager.getInstance(myContext) .beginWith(workC) .then(workD) val chain3 = WorkContinuation .combine(Arrays.asList(chain1, chain2)) .then(workE) chain3.enqueue()
Java
WorkContinuation chain1 = WorkManager.getInstance(myContext) .beginWith(workA) .then(workB); WorkContinuation chain2 = WorkManager.getInstance(myContext) .beginWith(workC) .then(workD); WorkContinuation chain3 = WorkContinuation .combine(Arrays.asList(chain1, chain2)) .then(workE); chain3.enqueue();
Dalam hal ini, WorkManager
menjalankan workA
sebelum workB
. WorkManager juga
menjalankan workC
sebelum workD
. Setelah workB
dan workD
selesai,
WorkManager
menjalankan workE
.
Ada sejumlah varian dari metode WorkContinuation
yang memberikan cara pintas untuk situasi tertentu. Untuk mengetahui detailnya, lihat referensi
WorkContinuation
.
Urutan pekerjaan unik
Anda dapat membuat urutan pekerjaan unik, dengan memulai setiap urutan dengan
panggilan ke
beginUniqueWork(String, ExistingWorkPolicy, OneTimeWorkRequest)
,
bukan beginWith(OneTimeWorkRequest)
.
Setiap urutan pekerjaan unik memiliki nama; WorkManager
hanya
mengizinkan satu urutan pekerjaan dengan suatu nama dalam satu waktu. Saat membuat urutan pekerjaan
unik yang baru, Anda menentukan apa yang harus dilakukan WorkManager
jika
sudah ada urutan yang belum selesai dengan nama yang sama:
- Membatalkan urutan yang ada dan MENGGANTI urutan tersebut dengan yang baru
- KEEP (MENYIMPAN) urutan yang ada dan mengabaikan permintaan yang baru
- MENAMBAHKAN urutan yang baru ke urutan yang sudah ada, menjalankan tugas pertama dari urutan yang baru setelah tugas terakhir urutan yang sudah ada telah selesai
Urutan pekerjaan unik dapat berguna saat Anda memiliki tugas yang tidak boleh diantrekan beberapa kali. Misalnya, jika aplikasi perlu menyinkronkan datanya ke jaringan, Anda dapat mengantrekan urutan bernama "sinkronisasi", dan menentukan bahwa tugas baru harus diabaikan jika sudah ada urutan dengan nama tersebut. Urutan pekerjaan unik juga berguna jika Anda perlu membuat rantai tugas panjang secara bertahap. Misalnya, aplikasi pengeditan foto dapat memungkinkan pengguna 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.
Parameter input dan nilai yang ditampilkan
Untuk fleksibilitas yang lebih besar, Anda dapat meneruskan argumen ke tugas dan meminta tugas
menampilkan hasilnya. Nilai yang diteruskan dan ditampilkan merupakan key-value pair. Untuk meneruskan
argumen ke tugas, panggil metode
WorkRequest.Builder.setInputData(Data)
sebelum Anda membuat objek
WorkRequest
. Metode tersebut mengambil objek Data
, yang Anda buat dengan
Data.Builder
. Class Worker
dapat mengakses argumen
tersebut dengan memanggil Worker.getInputData()
. Untuk
memperoleh output nilai yang ditampilkan, tugas harus menyertakannya di Result
(misalnya, menampilkan)
Result.success(Data)
.
Anda dapat memperoleh output dengan mengamati WorkInfo
tugas.
Misalnya, Anda memiliki class Worker
yang melakukan penghitungan yang
memerlukan waktu lama. Kode berikut menunjukkan seperti apa tampilan class
Worker
:
Kotlin
// Define the parameter keys: const val KEY_X_ARG = "X" const val KEY_Y_ARG = "Y" const val KEY_Z_ARG = "Z" // ...and the result key: const val KEY_RESULT = "result" // Define the Worker class: class MathWorker(context : Context, params : WorkerParameters) : Worker(context, params) { override fun doWork(): Result { val x = inputData.getInt(KEY_X_ARG, 0) val y = inputData.getInt(KEY_Y_ARG, 0) val z = inputData.getInt(KEY_Z_ARG, 0) // ...do the math... val result = myLongCalculation(x, y, z); //...set the output, and we're done! val output: Data = workDataOf(KEY_RESULT to result) return Result.success(output) } }
Java
// Define the Worker class: public class MathWorker extends Worker { // Define the parameter keys: public static final String KEY_X_ARG = "X"; public static final String KEY_Y_ARG = "Y"; public static final String KEY_Z_ARG = "Z"; // ...and the result key: public static final String KEY_RESULT = "result"; public MathWorker( @NonNull Context context, @NonNull WorkerParameters params) { super(context, params); } @Override public Result doWork() { // Fetch the arguments (and specify default values): int x = getInputData().getInt(KEY_X_ARG, 0); int y = getInputData().getInt(KEY_Y_ARG, 0); int z = getInputData().getInt(KEY_Z_ARG, 0); // ...do the math... int result = myLongCalculation(x, y, z); //...set the output, and we're done! Data output = new Data.Builder() .putInt(KEY_RESULT, result) .build(); return Result.success(output); } }
Untuk membuat tugas dan meneruskan argumen, Anda harus menggunakan kode seperti ini:
Kotlin
val myData: Data = workDataOf("KEY_X_ARG" to 42, "KEY_Y_ARG" to 421, "KEY_Z_ARG" to 8675309) // ...then create and enqueue a OneTimeWorkRequest that uses those arguments val mathWork = OneTimeWorkRequestBuilder<MathWorker>() .setInputData(myData) .build() WorkManager.getInstance(myContext).enqueue(mathWork)
Java
// Create the Data object: Data myData = new Data.Builder() // We need to pass three integers: X, Y, and Z .putInt(KEY_X_ARG, 42) .putInt(KEY_Y_ARG, 421) .putInt(KEY_Z_ARG, 8675309) // ... and build the actual Data object: .build(); // ...then create and enqueue a OneTimeWorkRequest that uses those arguments OneTimeWorkRequest mathWork = new OneTimeWorkRequest.Builder(MathWorker.class) .setInputData(myData) .build(); WorkManager.getInstance(myContext).enqueue(mathWork);
Nilai yang ditampilkan akan tersedia di WorkInfo
tugas:
Kotlin
WorkManager.getInstance(myContext).getWorkInfoByIdLiveData(mathWork.id) .observe(this, Observer { info -> if (info != null && info.state.isFinished) { val myResult = info.outputData.getInt(KEY_RESULT, myDefaultValue) // ... do something with the result ... } })
Java
WorkManager.getInstance(myContext).getWorkInfoByIdLiveData(mathWork.getId()) .observe(lifecycleOwner, info -> { if (info != null && info.getState().isFinished()) { int myResult = info.getOutputData().getInt(KEY_RESULT, myDefaultValue)); // ... do something with the result ... } });
Jika Anda merantai tugas, output dari satu tugas akan tersedia sebagai input untuk
tugas berikutnya pada rantai tersebut. Jika berupa rantai sederhana, dengan satu
OneTimeWorkRequest
yang diikuti dengan satu
OneTimeWorkRequest
lain, tugas pertama menampilkan hasilnya dengan
memanggil
Result.success(Data)
,
dan tugas berikutnya mengambil hasil tersebut dengan memanggil
getInputData()
. Jika
rantainya lebih rumit—misalnya, karena beberapa tugas semuanya mengirim output
ke satu tugas berikutnya—Anda dapat menentukan InputMerger
di OneTimeWorkRequest.Builder
untuk
menetapkan apa yang akan terjadi jika tugas yang berbeda menampilkan output dengan
kunci sama.
Referensi lainnya
Untuk mempelajari WorkManager lebih lanjut, lihat referensi tambahan berikut.
Contoh
- Contoh aplikasi WorkManager
- Sunflower, aplikasi berkebun yang mengilustrasikan praktik terbaik pengembangan Android dengan Android Jetpack.