Tạo luồng trong CoroutineWorker

Đối với người dùng Kotlin, WorkManager cung cấp dịch vụ hỗ trợ hàng đầu cho coroutine. Để bắt đầu, hãy đưa work-runtime-ktx vào tệp gradle của bạn. Thay vì mở rộng Worker, bạn nên mở rộng CoroutineWorker, vì lớp này có phiên bản tạm ngưng của doWork(). Ví dụ, nếu muốn tạo một CoroutineWorker đơn giản để thực hiện một số thao tác mạng, bạn cần làm như sau:

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()
    }
}

Xin lưu ý rằng CoroutineWorker.doWork() là môt hàm tạm ngưng. Không như Worker, mã này không chạy trên Executor được chỉ định trong Configuration của bạn. Thay vào đó, mặc định của mã này là Dispatchers.Default. Bạn có thể tuỳ chỉnh mã này bằng cách cung cấp CoroutineContext riêng của mình. Trong ví dụ trên, bạn có thể sẽ muốn thực hiện công việc này trên Dispatchers.IO như thế này:

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 tự động xử lý các trường hợp công việc bị dừng bằng cách huỷ coroutine và truyền đi các tín hiệu huỷ. Bạn không cần phải làm điều gì đặc biệt để xử lý các trường hợp công việc bị dừng.

Chạy CoroutineWorker trong một quy trình xử lý khác

Bạn cũng có thể liên kết worker với một quy trình cụ thể bằng cách sử dụng một cách triển khai ListenableWorkerRemoteCoroutineWorker.

RemoteCoroutineWorker liên kết với một quy trình cụ thể bằng 2 đối số bổ sung ARGUMENT_CLASS_NAMEARGUMENT_PACKAGE_NAME mà bạn cung cấp dưới dạng một phần của dữ liệu đầu vào khi tạo yêu cầu công việc.

Ví dụ sau đây minh hoạ việc xây dựng một yêu cầu công việc ràng buộc với một quy trình cụ thể:

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();

Đối với mỗi RemoteWorkerService, bạn cũng cần thêm định nghĩa dịch vụ vào tệp 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>

Mẫu