Threading di CoroutineWorker

Bagi pengguna Kotlin, WorkManager memberikan dukungan kelas satu untuk coroutine. Untuk memulai, sertakan work-runtime-ktx pada file gradle Anda. Sebagai ganti memperpanjang Worker, Anda harus memperpanjang CoroutineWorker, yang memiliki versi penangguhan doWork(). Misalnya, jika Anda ingin membuat CoroutineWorker sederhana untuk melakukan beberapa operasi jaringan, Anda dapat melakukan langkah berikut:

class CoroutineDownloadWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        val data = downloadSynchronously("https://www.google.com")
        saveData(data)
        return Result.success()
    }
}

Perhatikan bahwa CoroutineWorker.doWork() adalah fungsi penangguhan. Tidak seperti Worker, kode ini tidak berjalan pada Executor yang ditentukan dalam Configuration Anda. Sebagai gantinya, kode ini akan didefaultkan ke Dispatchers.Default. Anda dapat menyesuaikannya dengan menyediakan CoroutineContext Anda sendiri. Dalam contoh di atas, Anda dapat melakukan pekerjaan ini di Dispatchers.IO, seperti berikut:

class CoroutineDownloadWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        withContext(Dispatchers.IO) {
            val data = downloadSynchronously("https://www.google.com")
            saveData(data)
            return Result.success()
        }
    }
}

CoroutineWorker otomatis menangani penghentian dengan membatalkan coroutine dan menyebarkan sinyal pembatalan. Anda tidak perlu melakukan hal khusus untuk menangani penghentian pekerjaan.

Menjalankan CoroutineWorker dalam proses yang berbeda

Anda juga dapat mengikat pekerja ke proses tertentu menggunakan RemoteCoroutineWorker, implementasi ListenableWorker.

RemoteCoroutineWorker terikat ke proses tertentu dengan dua argumen tambahan yang Anda berikan sebagai bagian dari data input saat membuat permintaan pekerjaan: ARGUMENT_CLASS_NAME dan ARGUMENT_PACKAGE_NAME.

Contoh berikut menunjukkan pembuatan permintaan pekerjaan yang terikat dengan proses tertentu:

Kotlin

val PACKAGE_NAME = "com.example.background.multiprocess"

val serviceName = RemoteWorkerService::class.java.name
val componentName = ComponentName(PACKAGE_NAME, serviceName)

val data: Data = Data.Builder()
   .putString(ARGUMENT_PACKAGE_NAME, componentName.packageName)
   .putString(ARGUMENT_CLASS_NAME, componentName.className)
   .build()

return OneTimeWorkRequest.Builder(ExampleRemoteCoroutineWorker::class.java)
   .setInputData(data)
   .build()

Java

String PACKAGE_NAME = "com.example.background.multiprocess";

String serviceName = RemoteWorkerService.class.getName();
ComponentName componentName = new ComponentName(PACKAGE_NAME, serviceName);

Data data = new Data.Builder()
        .putString(ARGUMENT_PACKAGE_NAME, componentName.getPackageName())
        .putString(ARGUMENT_CLASS_NAME, componentName.getClassName())
        .build();

return new OneTimeWorkRequest.Builder(ExampleRemoteCoroutineWorker.class)
        .setInputData(data)
        .build();

Untuk setiap RemoteWorkerService, Anda juga perlu menambahkan definisi layanan di file AndroidManifest.xml:

<manifest ... >
    <service
            android:name="androidx.work.multiprocess.RemoteWorkerService"
            android:exported="false"
            android:process=":worker1" />

        <service
            android:name=".RemoteWorkerService2"
            android:exported="false"
            android:process=":worker2" />
    ...
</manifest>

Contoh