本文档介绍如何迁移应用以使用 WorkManager 客户端库而非 GCMNetworkManager 库执行后台操作。应用调度后台作业的首选方法是使用 WorkManager。通过同时包含 WorkManager GCM 库,您可以在运行 API 级别 22 或更低级别的 Android 设备上,允许 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 库,当您的应用在不支持 JobScheduler 的设备(即运行 API 级别 22 或更低级别的设备)上运行时,这个库可让 WorkManager 使用 GCM 调度作业。如需了解如何添加库的完整详情,请参阅 WorkManager 使用入门。
修改清单
在实现 GCMNetworkManager 时,您按照 GcmNetworkManager
参考文档的说明向应用清单添加了 GcmTaskService
实例。GcmTaskService
会检查传入的任务,然后将其委托给任务处理程序。WorkManager 负责管理指派给您的工作器的任务委托,这样您不必再通过一个类来完成这项任务;只需从清单中移除 GcmTaskService
即可。
定义工作器
您的 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 等效限制条件。本部分列出了这些等效限制条件。
对于 GCMNetworkManager 任务,可以在任务的 Builder 对象中调用相应方法来设置其限制条件;例如,您可以调用 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 作业设置标记,请先调用 WorkRequest.Builder.addTag()
方法,再使用该 Builder 创建 WorkRequest
。
在 GCMNetworkManager 中,您可以调用 setUpdateCurrent()
来指定任务是否应替换具有相同标记的任何现有任务。等效的 WorkManager 方法是通过调用 enqueueUniqueWork()
或 enqueueUniquePeriodicWork()
将任务加入队列的;如果使用这些方法,则需要为作业指定唯一名称,还要指定在存在具有该名称的待处理作业时,WorkManager 应如何处理请求。有关详情,请参阅处理唯一工作。
任务参数
您可以通过调用 Task.Builder.setExtras()
并传递包含参数的 Bundle
,将参数传递给 GCMNetworkManager 作业。WorkManager 支持向 WorkManager 作业传递 Data
对象,您可以将参数作为键值对包含在该对象中。如需了解详情,请参阅分配输入数据。