本文档说明了如何将应用迁移到使用 WorkManager 客户端库执行后台操作,而不是使用 GCMNetworkManager 库。应用计划后台作业的首选方法是使用 WorkManager。通过同时包含 WorkManager GCM 库,您可以使 WorkManager 在 Android 设备(运行 API 级别 22 或更低版本)上使用 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
对象并调用该对象的 methods 来设置约束(例如,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 作业,其中包含参数作为键/值对。有关详细信息,请参阅分配输入数据。