对于 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
您还可以通过使用 RemoteCoroutineWorker
(ListenableWorker
的实现)将工作者绑定到特定进程。
RemoteCoroutineWorker
使用您在构建工作请求时作为输入数据的一部分提供的两个额外参数绑定到特定进程:ARGUMENT_CLASS_NAME
和 ARGUMENT_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>