本文档说明了如何将应用程序迁移到使用 WorkManager 客户端库来执行后台操作,而不是使用 GCMNetworkManager 库。应用程序安排后台作业的首选方法是使用 WorkManager。通过还包含 WorkManager GCM 库,您可以在 Android 设备(运行 API 级别 22 或更低版本)上运行时,使 WorkManager 能够使用 GCM 来安排任务。
迁移到 WorkManager
如果您的应用程序当前使用 GCMNetworkManager 来执行后台操作,请按照以下步骤迁移到 WorkManager。
对于以下步骤,我们假设您从以下 GCMNetworkManager 代码开始,该代码定义并安排了您的任务
Kotlin
val myTask = OneoffTask.Builder() // setService() says what class does the work .setService(MyUploadService::class.java) // Don't run the task unless device is charging .setRequiresCharging(true) // Run the task between 5 & 15 minutes from now .setExecutionWindow(5 * DateUtil.MINUTE_IN_SECONDS, 15 * DateUtil.MINUTE_IN_SECONDS) // Define a unique tag for the task .setTag("test-upload") // ...finally, build the task and assign its value to myTask .build() GcmNetworkManager.getInstance(this).schedule(myTask)
Java
// In GcmNetworkManager, this call defines the task and its // runtime constraints: OneoffTask myTask = new OneoffTask.Builder() // setService() says what class does the work .setService(MyUploadService.class) // Don't run the task unless device is charging .setRequiresCharging(true) // Run the task between 5 & 15 minutes from now .setExecutionWindow( 5 * DateUtil.MINUTE_IN_SECONDS, 15 * DateUtil.MINUTE_IN_SECONDS) // Define a unique tag for the task .setTag("test-upload") // ...finally, build the task and assign its value to myTask .build(); GcmNetworkManager.getInstance(this).schedule(myTask);
在此示例中,我们假设 MyUploadService
定义了实际的上传操作
Kotlin
class MyUploadService : GcmTaskService() { fun onRunTask(params: TaskParams): Int { // Do some upload work return GcmNetworkManager.RESULT_SUCCESS } }
Java
class MyUploadService extends GcmTaskService { @Override public int onRunTask(TaskParams params) { // Do some upload work return GcmNetworkManager.RESULT_SUCCESS; } }
包含 WorkManager 库
要使用 WorkManager 类,您需要将 WorkManager 库添加到您的构建依赖项中。您还需要添加 WorkManager GCM 库,它使 WorkManager 能够在应用程序在不支持 JobScheduler 的设备(即运行 API 级别 22 或更低版本的设备)上运行时使用 GCM 进行作业调度。有关添加库的完整详细信息,请参阅 WorkManager 入门。
修改您的清单
在您实现 GCMNetworkManager 时,您将 GcmTaskService
的实例添加到您的应用程序清单中,如 GcmNetworkManager
的 参考文档 中所述。 GcmTaskService
查看传入的任务并将其委托给任务处理程序。WorkManager 管理对 Worker 的任务委托,因此您不再需要执行此操作的类;只需从清单中删除您的 GcmTaskService
。
定义 Worker
您的 GCMNetworkManager 实现定义了 OneoffTask
或 RecurringTask
,它指定了需要完成的工作。您需要将其重写为 Worker
,如 定义您的工作请求 中所述。
GCMNetworkManager 示例代码 定义了一个 myTask
任务。WorkManager 等效项如下所示
Kotlin
class UploadWorker(context: Context, params: WorkerParameters) : Worker(context, params) { override fun doWork() : Result { // Do the upload operation ... myUploadOperation() // Indicate whether the task finished successfully with the Result return Result.success() } }
Java
public class UploadWorker extends Worker { public UploadWorker( @NonNull Context context, @NonNull WorkerParameters params) { super(context, params); } @Override public Result doWork() { // Do the upload operation ... myUploadOperation() // Indicate whether the task finished successfully with the Result return Result.success() } }
GCM 任务和 Worker
之间存在一些差异
- GCM 使用
TaskParams
对象将参数传递给任务。WorkManager
使用输入数据,您可以在WorkRequest
上指定,如WorkManager
文档中针对 定义任务的输入/输出 所述。在这两种情况下,您都可以传递键/值对,指定任务所需的任何持久化参数。 GcmTaskService
通过返回诸如GcmNetworkManager.RESULT_SUCCESS
之类的标志来表示成功或失败。WorkManagerWorker
通过使用ListenableWorker.Result
方法(如ListenableWorker.Result.success()
)并返回该方法的返回值来表示其结果。- 正如我们提到的,您不会在定义
Worker
时设置约束或标签;而是在下一步中创建WorkRequest
时进行设置。
安排工作请求
定义 Worker
指定了要完成的工作。要指定工作应何时完成,您需要定义 WorkRequest
- 创建
OneTimeWorkRequest
或PeriodicWorkRequest
,并设置任何所需的约束,以指定任务应何时运行,以及任何用于标识您的工作的标签。 - 将请求传递给
WorkManager.enqueue()
,以将任务排队以供执行。
例如,上一节展示了如何将OneoffTask
转换为等效的Worker
。但是,该Worker
没有包含OneoffTask
对象的执行约束和标签。相反,我们在创建WorkRequest
时设置了约束和任务 ID。我们还将指定该任务必须在存在网络连接的情况下才能运行。您无需使用 GCMNetworkManager 显式请求网络连接,因为 GCMNetworkManager 默认情况下需要网络连接,但 WorkManager 除非您专门添加该约束,否则不需要网络连接。定义了WorkRequest
后,我们使用 WorkManager 将其排队。
Kotlin
val uploadConstraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .setRequiresCharging(true).build() val uploadTask = OneTimeWorkRequestBuilder<UploadWorker>() .setConstraints(uploadConstraints) .build() WorkManager.getInstance().enqueue(uploadTask)
Java
Constraints uploadConstraints = new Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .setRequiresCharging(true) .build(); OneTimeWorkRequest uploadTask = new OneTimeWorkRequest.Builder(UploadWorker.class) .setConstraints(uploadConstraints) .build(); WorkManager.getInstance().enqueue(uploadTask);
API 映射
本节介绍一些 GCMNetworkManager 功能和约束如何映射到 WorkManager 等效项。
约束映射
GCMNetworkManager 允许您在任务应运行时设置一些约束。在大多数情况下,存在清晰的等效 WorkManager 约束。本节列出了这些等效项。
通过在任务的 Builder 对象中调用相应的方法来设置 GCMNetworkManager 任务的约束;例如,您可以通过调用Task.Builder.setRequiredNetwork()
来设置网络要求。
在 WorkManager 中,您将创建一个Constraints.Builder
对象,并调用该对象的某些方法来设置约束(例如,Constraints.Builder.setRequiredNetworkType())
,然后使用 Builder 创建一个 Constraints 对象,您可以将其附加到工作请求。有关更多信息,请参阅定义工作请求。
GCMNetworkManager 约束 | WorkManager 等效项 | 说明 |
---|---|---|
setPersisted() |
(不需要) | 所有 WorkManager 作业都会在设备重启后持久保留 |
setRequiredNetwork() |
setRequiredNetworkType() |
默认情况下,GCMNetworkManager 需要网络访问权限。WorkManager 默认情况下不需要网络访问权限。如果您的作业需要网络访问权限,则必须使用setRequiredNetworkType(CONNECTED) ,或设置一些更具体的网络类型。 |
setRequiresCharging() |
其他映射
除了约束之外,您还可以对 GCMNetworkManager 任务应用其他设置。本节列出了将这些设置应用于 WorkManager 作业的对应方法。
标签
所有 GCMNetworkManager 任务都必须具有一个标签字符串,您可以通过调用 Builder 的setTag()
方法来设置该字符串。WorkManager 作业由 ID 唯一标识,该 ID 由 WorkManager 自动生成;您可以通过调用WorkRequest.getId()
获取该 ID。此外,工作请求可以选择性地具有一个或多个标签。要为 WorkManager 作业设置标签,请在使用该 Builder 创建WorkRequest
之前,调用WorkRequest.Builder.addTag()
方法。
在 GCMNetworkManager 中,您可以调用setUpdateCurrent()
来指定任务是否应替换具有相同标签的任何现有任务。等效的 WorkManager 方法是通过调用enqueueUniqueWork()
或enqueueUniquePeriodicWork()
来排队任务;如果您使用这些方法,您将为作业提供一个唯一的名称,并指定 WorkManager 应如何在存在具有该名称的挂起作业时处理请求。有关更多信息,请参阅处理唯一工作。
任务参数
您可以通过调用Task.Builder.setExtras()
并传递包含参数的Bundle
来将参数传递给 GCMNetworkManager 作业。WorkManager 允许您将一个Data
对象传递给 WorkManager 作业,该对象包含参数作为键值对。有关详细信息,请参阅分配输入数据。