Nowadays, WorkManager is one of the Android Architecture Components and also a part of Android Jetpack as a new approach for developing modern Android apps. As a matter of fact, the WorkManager API is a suitable and recommended replacement for all previous Android background scheduling APIs. WorkManager is an API that makes it easy to schedule deferrable, asynchronous tasks, which are expected to run even if the app exits or the device restarts. This essay will discuss some main concepts in working with WorkManager, and explain some key steps for implementing in an Android app as well.
如今,WorkManager是Android体系结构组件之一,也是Android Jetpack的一部分,作为开发现代Android应用程序的新方法。 实际上,WorkManager API是所有以前的Android后台调度API的合适且推荐的替代品。 WorkManager是一种API,可轻松安排可延迟的异步任务,即使应用程序退出或设备重新启动,这些任务也有望运行。 本文将讨论使用WorkManager的一些主要概念,并解释一些在Android应用程序中实现的关键步骤。
简介与概述 (Introduction and Overview)
Practically, your app will not always be in the foreground; however, you still need to do some significant background works such as downloading updates, and syncing with your server. Currently, there are a number of existing APIs for this purpose with their own particular use cases as follow: JobScheduler, Loader, Service, AsyncTask, Firebase JobDispatcher, GCM Network Manager, and AlarmManager.
实际上,您的应用不会总是处于前台。 但是,您仍然需要做一些重要的后台工作,例如下载更新和与服务器同步。 当前,有许多用于此目的的现有API及其特定用例如下:JobScheduler,Loader,Service,AsyncTask,Firebase JobDispatcher,GCM Network Manager和AlarmManager。
In fact, before discussing what background execution is, we require to have a clear vision toward understanding an app to be in the foreground. An app is considered to be in the foreground if one of the following cases would be accomplished:
实际上,在讨论什么是后台执行之前,我们需要对理解应用程序处于前台具有清晰的认识。 如果满足以下情况之一,则认为该应用程序处于前台:
- The Android app has a visible activity. Android应用有可见活动。
2. The Android app has a foreground service.
2. Android应用程序具有前台服务 。
3. Another foreground application is associated to the app by binding to one of its services, or using one of its content providers.
3.另一个前台应用程序通过绑定到其服务之一或使用其内容提供商之一而与该应用程序相关联。
4. IME
4. 输入法
5. Wallpaper service
5. 墙纸服务
6. Notification listener
6. 通知监听器
7. Voice or text service
7. 语音或文字服务
8. Music application when streaming music to your car.
8.将音乐流式传输到汽车上时的音乐应用程序。
As a result, if none of those situations is correct, the Android app is recognized to be in the background. Running tasks in the background consumes a device’s limited resources such as RAM and battery. This leads to affect user experiences . For instance, background tasks may diminish the battery life of the device at times such as watching a video, playing a game, or using the camera. Thus, to enhance battery life and give an appropriate user experience, Android has introduced a lot of battery-saving features in recent releases. These features manage and balance the power usage of applications as follows:
结果,如果所有这些情况都不正确,则将Android应用识别为后台。 在后台运行任务会消耗设备有限的资源,例如RAM和电池。 这会影响用户体验。 例如,在观看视频,玩游戏或使用相机等时间,后台任务可能会缩短设备的电池寿命。 因此,为了延长电池寿命并提供适当的用户体验,Android在最新版本中引入了许多省电功能。 这些功能按以下方式管理和平衡应用程序的电源使用:
App Standby Buckets: It helps the system prioritize apps’ requests for resources based on how recently and how frequently the apps are used.
应用程序备用存储桶 :它可以帮助系统根据应用程序的使用频率和使用频率对应用程序的资源请求进行优先级排序。
2. Background Service Limitations: It restricts background services from being run and consuming CPU/network in a hidden/non-visible way.
2.后台服务限制:它限制后台服务以隐藏/不可见的方式运行和消耗CPU /网络。
3. Doze and App Standby: It restricts Android app behavior when the screen is off, and the device is idle and not charging.
3.打ze和应用待机:当屏幕关闭且设备处于空闲状态且未充电时,它将限制Android应用的行为。
4. Background Location Limits: To reduce power consumption, Android 8.0 (API level 26) limits how frequently background apps can retrieve the user’s current location. Apps can receive location updates only a few times each hour.
4.后台位置限制:为了降低功耗,Android 8.0(API级别26)限制了后台应用检索用户当前位置的频率。 应用每小时只能接收几次位置更新。
As an Android developer, you have to work with these battery-saving features to make sure your background tasks run across API levels. This issue can add code complexity to your project. For instance, for working background task on all API levels, you may have these lines of codes:
作为Android开发人员,您必须使用这些省电功能来确保后台任务在API级别上运行。 此问题可能会增加项目的代码复杂度。 例如,对于所有API级别的后台工作,您可能需要以下几行代码:
if (userAPILevel >= VERSION_CODES.M) { //Running background task on devices M+} else if (userAPILevel >= VERSION_CODES.LOLLIPOP) { //Running background task on devices L+} else if ( … ) { //Rest of your codes
}
However, if you do not perform this matter properly, you will face that your background work will not run for on all devices. This is the exact case that WorkManager library could be helpful for addressing these issues. WorkManager is one of the Android Architecture Components and also is a part of Android Jetpack as a new approach for developing modern Android apps. For example, you might point your app to download new resources from the network occasionally. So, the downloading is a task and you can set up this task to run at an appropriate time based on the availability of the WiFi network or when the device is charging. Now, you can be able to schedule a task by using WorkManager
但是,如果您不能正确执行此操作,将面临您的后台工作不会在所有设备上运行的情况。 这正是WorkManager库可能有助于解决这些问题的确切情况。 WorkManager是Android体系结构组件之一 ,也是Android Jetpack的一部分,是开发现代Android应用程序的新方法。 例如,您可能会指向您的应用偶尔从网络下载新资源。 因此,下载是一项任务,您可以将该任务设置为根据WiFi网络的可用性或设备正在充电的时间在适当的时间运行。 现在,您可以使用WorkManager安排任务
使用WorkManager安排任务 (Scheduling tasks with WorkManager)
Initially, WorkManager provides a unified solution for background works, and also covers Android’s power-saving features as well as the user’s API levels. It is backwards compatible to API level 14. In addition, it can be run with or without Google Play services. These unique features make it the recommended solution for most background work on Android. There are two key attributes that make a task suitable for WorkManager. First, that the task is deferrable, and second, that the task requires to be guaranteed to run.
最初,WorkManager为后台工作提供了统一的解决方案,还涵盖了Android的节能功能以及用户的API级别。 它向后兼容API级别14。此外,它可以在有或没有Google Play服务的情况下运行。 这些独特的功能使其成为Android上大多数后台工作的推荐解决方案。 有两个关键属性使任务适合WorkManager。 首先,任务是可延迟的 ,其次,需要保证任务能够运行。
WorkManager is an API that makes it easy to schedule deferrable, asynchronous tasks that are expected to run even if the app exits or the device restarts.
WorkManager是一个API,即使应用程序退出或设备重新启动,也可以轻松地计划可运行的异步任务。
Deferrable: The task can run later and is still useful.
可延缓 : 该任务可以稍后运行,仍然有用。
Deferrable work is any task that is still useful even if it is not run immediately. So, sending analytic data to your server is wholly deferrable work; however, sending an instant message is not deferrable.
可延期工作是即使没有立即运行也仍然有用的任何任务。 因此,将分析数据发送到您的服务器是完全可推迟的工作。 但是,发送即时消息是不可推迟的。
2. Guaranteed: The task runs even if the device restarts.
2. 保证 : 即使设备重新启动,任务也会运行。
Guaranteed work means that the task will run if the application process is killed or the device is restarted. Thus, an important example for WorkManager would be backing up pictures to a server. This work can be deferred, but it should be guaranteed to run as well.
保证工作意味着如果应用程序进程终止或设备重新启动,任务将运行。 因此,WorkManager的一个重要示例是将图片备份到服务器。 可以推迟这项工作,但也应保证它也可以运行。
Besides, WorkManager could be paired with other APIs like Firebase Cloud Messaging to trigger background work. Thus; for example, when there is data for syncing on your server, you can be able to use an FCM message to notify your app and then perform the real syncing with WorkManager. Another key point is that even though WorkManager is a powerful strategy, background work cannot be a replacement for all approaches. This means WorkManager is not a replacement for Executors + Threadpools, Kotlin Coroutines, and RxJava. Additionally, WorkManager is not designed to trigger a work at an exact time. For achieving this goal, you will need to use an API like AlarmManager, or start a foreground service if your users expect your tasks to occur promptly.
此外,WorkManager可以与Firebase Cloud Messaging等其他API配对以触发后台工作。 从而; 例如,当服务器上有要同步的数据时,您可以使用FCM消息通知您的应用,然后与WorkManager进行真正的同步。 另一个关键点是,即使WorkManager是一种强大的策略,后台工作也不能替代所有方法。 这意味着WorkManager不能替代Executors + Threadpools,Kotlin Coroutines和RxJava。 此外,WorkManager并非旨在在准确的时间触发工作。 为了实现此目标,您将需要使用如AlarmManager之类的API,或者如果用户希望您的任务Swift完成,则启动前台服务。
Google Documents Google Documents提供实施WorkManager计划任务的步骤 (Step for implementation WorkManager to Schedule Tasks)
There are some main steps for implementing WorkManager in your Android projects, which are represented in this section respectively.
本节分别介绍了在Android项目中实现WorkManager的一些主要步骤。
Adding the WorkManager dependency
添加WorkManager依赖项
In fact, the KTX version of the library provides some Extension Functions in Kotlin. You can use the KTX version of WorkManager using this dependency app/build.gradle file:
实际上,该库的KTX版本在Kotlin中提供了一些扩展功能。 您可以使用此依赖app / build.gradle文件使用KTX 版本的WorkManager :
dependencies { def work_version = "2.3.4"
implementation "android.arch.work:work-runtime-ktx:$work_version"}
If you want to use the Java dependency, you must remove the “-ktx” from the above dependency.
如果要使用Java依赖项,则必须从上述依赖项中删除“ -ktx”。
Defining the Worker
定义工人
In this step you should define what your task does by using a worker. All the code summarize into the doWork() method. Furthermore, Workers accept inputs and produce outputs, and both inputs and outputs are represented as key, value pairs. Another significant point is that a Worker always return a value for representing success, failure, or retry. For instance, if you want to upload an image with WorkManager, you should implement a class as follow:
在此步骤中,您应该定义使用工作程序执行的任务。 所有代码都汇总到doWork()方法中。 此外,工作人员接受输入并产生输出,并且输入和输出均表示为关键值对。 另一个重要的一点是,工作程序始终返回代表成功,失败或重试的值。 例如,如果要使用WorkManager上传图像,则应实现如下类:
class UploadWorker(appContext: Context, workerParams: WorkerParameters)
: Worker(appContext, workerParams) {
override fun doWork(): Result {
try {
// Get the input
val imageUriInput = inputData.getString(Constants.KEY_IMAGE_URI)
// Do the work
val response = upload(imageUriInput)
// Create the output of the work
val imageResponse = response.body()
val imgLink = imageResponse.data.link
// workDataOf (part of KTX) converts a list of pairs to a [Data] object.
val outputData = workDataOf(Constants.KEY_IMAGE_URI to imgLink)
return Result.success(outputData)
} catch (e: Exception) {
return Result.failure()
}
}
fun upload(imageUri: String): Response {
TODO(“Webservice request code here”)
// Webservice request code here; note this would need to be run
// synchronously for reasons explained below.
}
}
The input and output are passed as Data that is essentially a map of primitive types and arrays. Data objects have some restrictions on the total size, which can be input and output. This is set by the MAX_DATA_BYTES
. If you need to pass more data for input and output of your worker, you should set your data in another place like Room database.
输入和输出作为Data传递, Data本质上是原始类型和数组的映射。 数据对象对总大小有一些限制,可以输入和输出。 这是由MAX_DATA_BYTES
设置的。 如果您需要传递更多数据以供工人输入和输出,则应将数据设置在另一个位置,例如Room database 。
Creating WorkRequest
创建工作请求
In this step you should make a request by using a class that is called WorkRequest. The WorkRequest is basically a class for configuring when and how task will be run. As part of the WorkRequest, you can add Constraints, specify the input, and choose to run the work once (OneTimeWorkRequest) or periodically ( PeriodicWorkRequest
). In uploading an image as an example, because this task is non-repeating work, OneTimeWorkRequest is used.
在这一步中,您应该使用称为WorkRequest的类发出请求。 WorkRequest基本上是用于配置何时以及如何运行任务的类。 作为WorkRequest的一部分,您可以添加Constraints ,指定输入,然后选择一次运行工作( OneTimeWorkRequest )或定期运行工作( PeriodicWorkRequest
)。 以上载图像为例,由于此任务是非重复性的工作, 因此使用OneTimeWorkRequest 。
val imageData = workDataOf(Constants.KEY_IMAGE_URI to imageUriString)
val uploadWorkRequest = OneTimeWorkRequestBuilder()
.setInputData(imageData)
.build()
Furthermore, if you do not always run promptly because of checking for checking for network connection on device, you can do this matter by adding a Constraints
object as follows:
此外,如果由于检查设备上的网络连接而不总是立即运行,则可以通过添加Constraints
对象来做到这一点,如下所示:
val constraints = Constraints.Builder()
.setRequiresBatteryNotLow(true)
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(true)
.setRequiresStorageNotLow(true)
.setRequiresDeviceIdle(true)
.build()
Enqueue the WorkRequest
排队工作请求
At this point, you should schedule your work by adding this line of code, which includes WorkManager singleton instance and enqueue method for scheduling:
此时,您应该通过添加以下代码行来安排工作,其中包括WorkManager单例实例和用于计划的enqueue方法:
WorkManager.getInstance().enqueue(uploadWorkRequest)
Updating UI
更新UI
At present, if you want to update the UI when your work finishes, you should use the getWorkInfoByIdLiveData method to obtain a WorkInfo LiveData. In fact, the WorkInfo is wrapped by LiveData for making it observable. WorkInfo has all of the information about the current state of your work, including the status of the work and the optional output. For example, if you want to show a message to the user when some works finishes successfully, you could set it up as follows:
当前,如果要在工作完成时更新UI,则应使用getWorkInfoByIdLiveData方法 获得WorkInfo LiveData 。 实际上, WorkInfo由LiveData封装以使其可观察。 WorkInfo包含有关您工作当前状态的所有信息,包括工作状态和可选输出。 例如,如果要在某些作品成功完成时向用户显示消息,则可以按以下方式进行设置:
WorkManager.getInstance(myContext).getWorkInfoByIdLiveData(uploadWorkRequest.id)
.observe(lifecycleOwner, Observer { workInfo ->
if (workInfo != null && workInfo.state == WorkInfo.State.SUCCEEDED) {
display Message("Work is done!")
}
})
在WorkManager的幕后 (Under the hood of WorkManager)
As you know, WorkManager is backwards compatible to API level 14 and runs without Google Play Services. To make sure this issue, WorkManager chooses between JobScheduler and a combination of AlarmManager and Broadcast Receivers when running. To guarantee that the work keeps running, all information about enqueued work is kept in a WorkManager-managed database; therefore, it can be resumed if it is stopped.
如您所知,WorkManager向后兼容API级别14,并且无需使用Google Play服务即可运行。 为确保此问题,WorkManager在运行时在JobScheduler以及AlarmManager和广播接收器的组合之间进行选择。 为了确保工作继续运行,所有与排队工作有关的信息都保存在WorkManager管理的数据库中。 因此,如果停止,它可以恢复。
All in all, WorkManager uses an underlying job dispatching service based on the following criteria under the hood:
总而言之,WorkManager在幕后基于以下条件使用基础的作业调度服务:
Google Documents Google Documents提供穿线选项 (Threading Options)
Basically, Worker uses an executor behind the scenes. So, if you want to manage threading in some other ways, there are RxWorker and CoroutineWorker as options for accomplishing. Also, for having more control on the process, you can make your own Worker class by extending ListenableWorker and defining your exact threading strategy.
基本上,Worker在后台使用执行程序。 因此,如果您想以其他方式管理线程,则可以使用RxWorker和CoroutineWorker作为完成的选项。 另外,为了更好地控制流程,您可以通过扩展ListenableWorker来制作自己的Worker类 并定义您的确切线程策略。
链条 (Chains)
WorkManager allows you to create and enqueue a chain of work that specifies multiple dependent tasks, and defines what order they should run in. This is particularly helpful when you require to run several tasks in a special order. For instance, an application runs image filters on three various images as parallel, then compresses those images together, and then uploads them.
WorkManager允许您创建并排队一个工作链,以指定多个相关任务,并定义它们应以什么顺序运行。当您需要以特殊顺序运行多个任务时,这特别有用。 例如,应用程序在三个不同的图像上并行运行图像过滤器,然后将这些图像压缩在一起,然后上载它们。
WorkManager.getInstance(myContext)
.beginWith(listOf(filter1, filter2, filter3))
.then(compress)
.then(upload)
.enqueue()
WorkManager的优点 (Advantages of WorkManager)
- You can schedule a task depending on the condition when they should run. So WorkManager give the guarantee that the task will be executed even when the device is rebooted. 您可以根据任务的运行时间安排任务。 因此,WorkManager保证即使重新启动设备也会执行任务。
2. It provides backward compatibility, which means you do not have to specify the device capabilities or choose an appropriate API.
2.它提供了向后兼容性,这意味着您不必指定设备功能或选择适当的API。
3. You can detect and track the status of your tasks.
3.您可以检测并跟踪任务的状态。
4. It provides task chaining. It means you can create a draft of your work, and enqueue one after the other using the WorkManager.
4.它提供任务链。 这意味着您可以创建工作草稿,然后使用WorkManager依次入队。
结论 (In conclusion)
This essay considered some main concepts in using WorkManager, and defined some key steps for implementing in an Android project as well. Basically, WorkManager supports a unified solution for background works, and also covers Android’s power-saving features as well as the user’s API levels. So, you can schedule a task by using WorkManager efficiently in Android app development.
本文考虑了使用WorkManager的一些主要概念,并定义了一些在Android项目中实现的关键步骤。 基本上,WorkManager支持后台工作的统一解决方案,并且还涵盖了Android的节能功能以及用户的API级别。 因此,您可以通过在Android应用程序开发中有效使用WorkManager来安排任务。
翻译自: https://medium.com/kayvan-kaseb/using-android-workmanager-8781559b5a1d