CoroutineWorker 中的线程

对于 Kotlin 用户,WorkManager 提供了对 协程 的一流支持。要开始使用,请在您的 Gradle 文件中包含 work-runtime-ktx。您应该扩展 CoroutineWorker 而不是扩展 Worker,它具有 doWork() 的挂起版本。例如,如果您想构建一个简单的 CoroutineWorker 来执行一些网络操作,您将执行以下操作

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

请注意,CoroutineWorker.doWork() 是一个挂起函数。与 Worker 不同,此代码不会在您在 Configuration 中指定的 Executor 上运行。相反,它默认为 Dispatchers.Default。您可以通过提供自己的 CoroutineContext 来自定义它。在上面的示例中,您可能希望在 Dispatchers.IO 上执行此工作,如下所示

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 通过取消协程并传播取消信号来自动处理停止。您无需执行任何特殊操作即可处理 工作停止

在不同的进程中运行 CoroutineWorker

您还可以通过使用 RemoteCoroutineWorkerListenableWorker 的实现)将工作者绑定到特定进程。

RemoteCoroutineWorker 使用您在构建工作请求时作为输入数据的一部分提供的两个额外参数绑定到特定进程:ARGUMENT_CLASS_NAMEARGUMENT_PACKAGE_NAME

以下示例演示了构建绑定到特定进程的工作请求

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

对于每个 RemoteWorkerService,您还需要在您的 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>

示例