xml即时更新
本文的重点 (Takeaway from this article)
This blog post focus on how to implement long-running background tasks that need to start immediately with WorkManager. You need to be familiar with the basics of WorkManager before going any further, so I would recommend learning from here.
这篇博客文章重点介绍如何实施需要立即从WorkManager 开始的长期运行的后台任务。 在进行任何后续操作之前,您需要熟悉WorkManager的基础,所以我建议从这里学习。
总览 (Overview)
One thing that is constantly changing in the android environment is how we handle background tasks. When the number of apps increased in the phone, the number of background tasks will also increase; most of the apps won’t check for battery health before starting their job, which leads to drain the battery in a short time.
在android环境中不断变化的一件事是我们如何处理后台任务。 当手机中的应用程序数量增加时,后台任务的数量也会增加; 大多数应用在开始工作之前不会检查电池的运行状况,这会在短时间内耗尽电池电量。
WorkManager is a jetpack library to help developers execute their long-running background tasks in the best way possible without affecting system health.
WorkManager是jetpack库,可帮助开发人员以最佳方式执行其长期运行的后台任务,而不影响系统运行状况。
WorkManager是: (WorkManager is:)
- Compatible with API level 14 兼容API级别14
- Runs with/without Google Play Services 与/不与Google Play服务一起运行
WorkManager如何执行后台任务? (How WorkManager execute background tasks?)
When we add a request to the WorkManager queue, we also add constraints(requirements to execute your request, such as network connection).
当我们向WorkManager队列添加请求时,我们还会添加约束(执行请求的要求,例如网络连接)。
Once you add the request, first, WorkManager checks the system health based on the already executing requests, and then it’ll verify whether all the constraints of the request are satisfied. This will result in two cases: success and failure.
添加请求后,首先,WorkManager根据已经执行的请求检查系统运行状况,然后验证是否满足请求的所有约束。 这将导致两种情况:成功和失败。
Success: When both conditions are satisfied, it’ll add the request to the queue of execution. When the time comes, your request will execute.
成功:当两个条件都满足时,它将请求添加到执行队列中。 时间到了,您的请求将执行。
Failure: When either of the conditions fails, it’ll hold the request until they are satisfied.
失败:当任何一个条件失败时,它将暂停请求,直到满足条件为止。
WorkManager has become a viable solution to execute deferrable and guaranteed background tasks due to the above reasons.
由于上述原因,WorkManager已成为执行可延期且有保证的后台任务的可行解决方案。
WorkManager如何执行即时任务? (How WorkManager execute immediate tasks?)
There will be circumstances when it comes to reality when we need to start a background task immediately. Starting with WorkManager version 2.3.0, every Worker can access functions to execute tasks in a foreground service. The Worker base class, ListenableWorker
, and provides a new setForegroundAsync()
function.
在某些情况下,当我们需要立即启动后台任务时,就会变成现实。 从WorkManager 版本2.3.0开始 ,每个Worker都可以访问功能以执行前台服务中的任务。 Worker基类ListenableWorker
,并提供了一个新的setForegroundAsync()
函数。
First, let’s learn how this works, with the access to setForegroundAsync()
function we can communicate to WorkManager that this task needs to start right away.
首先,让我们了解其工作原理,通过访问setForegroundAsync()
函数,我们可以与WorkManager交流该任务需要立即开始的信息。
On the other side, WorkManager internally deals with this request as a foreground service instead of a complete background task, and it’ll initiate the request right away.
另一方面,WorkManager在内部将此请求作为前台服务而不是完整的后台任务处理,并且它将立即启动该请求。
如何创建一个立即执行的Worker? (How to create a Worker that executes right away?)
Now that we know how these things work, it’s time to learn how to implement them. I used a coroutine worker in this post, but it’s the same implementation with normal workers and Rxworker.
现在我们知道了这些事情是如何工作的,是时候学习如何实现它们了。 我在这篇文章中使用了协程工人,但与普通工人和Rxworker的实现相同。
Let’s start from basic. First, we need to implement a general coroutine worker. We need to create a class and extend it with CoroutineWorker
then override the doWork
function with success and failure cases. Have a look:
让我们从基础开始。 首先,我们需要部署一名普通协程工人。 我们需要创建一个类,并使用CoroutineWorker
进行扩展,然后使用成功案例和失败案例重写doWork
函数。 看一看:
class CoroutineDownloadWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
try {
// code to be executed
return Result.success()
} catch (throwable: Throwable) {
// clean up and log
return Result.failure()
}
}
}
In the doWork
function, we’ve to tell the WorkManager that it should start immediately via setForeground
function. This function takes ForegroundInfo
as a parameter. To build ForegroundInfo
, we need a notification id as well as the notification.
在doWork
函数中,我们必须告诉WorkManager它应该立即通过setForeground
函数启动。 此函数将ForegroundInfo
作为参数。 要构建ForegroundInfo
,我们需要一个通知ID和一个通知。
创建通知 (Create Notification)
First, we need to create a notification for devices with Android 8.0, and above, we need to create a notification channel too. This notification will be shown to the user while the task executes. See the below code to create a notification with notification channel:
首先,我们需要为装有Android 8.0的设备创建通知,而在以上版本中,我们也需要创建一个通知渠道。 该通知将在任务执行时显示给用户。 请参阅下面的代码以创建带有通知通道的通知:
private fun createNotification(): Notification {
val intent = WorkManager.getInstance(context).createCancelPendingIntent(id)
val builder = Builder(context, "channelId")
.setContentTitle(title)
.setSmallIcon(R.drawable.small_icon)
.setOngoing(true)
if (VERSION.SDK_INT >= VERSION_CODES.O) {
createNotificationChannel().also {
builder.setChannelId(it.id)
}
}
return builder.build()
}
@TargetApi(VERSION_CODES.O)
private fun createNotificationChannel(): NotificationChannel {
return NotificationChannel(
"channelId", "ChannelName", NotificationManager.IMPORTANCE_LOW
).also { channel ->
notificationManager.createNotificationChannel(channel)
}
}
创建前景信息 (Create ForegroundInfo)
Now, that we’re done with notification builder it’s time to create ForegroundInfo
with notification and id, as shown below:
现在,我们已经完成了通知构建器,是时候创建带有通知和id的ForegroundInfo
了,如下所示:
private fun createForegroundInfo(): ForegroundInfo {
// generate a random id for each notification
val notificationId = 1001
return ForegroundInfo(notificationId, createNotification())
}
在前台服务中执行工作程序 (Execute Worker in a foreground service)
Now, it’s finally time to bring pieces together and start the worker. But you should always remember that you need to invoke setForeground
with ForegroundInfo
before executing the task; otherwise, it’ll be treated as a background task. Have a look:
现在,是时候该将各个部分放在一起并开始工作了。 但是您应该始终记住,在执行任务之前,需要使用ForegroundInfo
调用setForeground
。 否则,它将被视为后台任务。 看一看:
override suspend fun doWork(): Result {
try {
setForeground(createForegroundInfo())
// code to be executed
return Result.success(workDataOf(KEY_RESULT to result))
} catch (throwable: Throwable) {
// clean up and log
return Result.failure()
}
}
奖金 (Bonus)
To know more about work-manager like how to use work-manager with RxJava, input & outputs of the worker, tagging a request, and more read the following articles.
要了解有关工作管理器的更多信息,例如如何将工作管理器与RxJava一起使用,工作器的输入和输出,标记请求以及更多内容,请阅读以下文章。
“WorkManager basics, how to use WorkManager with Rxjava2 & Kotlin Coroutines”
To learn more about Jetpack libraries read the following articles:
要了解有关Jetpack库的更多信息,请阅读以下文章:
“WorkManager basics, how to use WorkManager with Rxjava2 & Kotlin Coroutines”
“Jetpack Compose — A New and Simple Way to Create Material-UI in Android”
翻译自: https://medium.com/android-dev-hacks/workmanager-for-immediate-tasks-latest-update-5c6036945934
xml即时更新