共计 3231 个字符,预计需要花费 9 分钟才能阅读完成。
当须要执行长时间运行的工作,而利用处于后盾状态时,您会遇到 后盾执行限度,该个性是在 Android 8.0 之后减少的。咱们激励开发者进行行为变更以晋升整个平台的用户体验。
为了不同的应用场景更易于适配,咱们通过对 WorkManager 增加性能,晋升了开发者在遵循后台任务限度方面的体验。
咱们举荐应用 WorkManager 解决需立刻执行的长时间运行工作。
浏览本文,理解通过 WorkManager 解决的需长时间运行并且立刻执行的工作的益处以及如何进行配置。
API 介绍
自 WorkManager 版本 2.3.0 起,每个 Worker 都能够在前台服务中调用办法。ListenableWorker 作为 Worker 的基类,提供了新的 setForegroundAsync() 函数。
本文以 CoroutineWorker 为例。在 CoroutineWorker 中,setForegroundAsync() 被封装在一个挂起的 setForeground() 函数中。该类也提供挂起的 doWork 函数,它反对代码脱离主线程运行。然而,本文的全部内容同样实用于其余 Worker 类的相干函数。
当调用 setForeground(Async) 时,一旦满足约束条件,预约的工作将会在前台服务中立刻执行。此外,WorkManager 会负责解决服务的生命周期。而在前台服务的 Worker 中运行的工作也不会受到后台任务十分钟的限度。
从立刻执行开始
让咱们来看一下如何让一个已存在的 worker 在前台服务中执行工作。
咱们从一个非常简单的 doWork() 函数开始。代码是异步执行的,无论胜利或失败,都会有相应的 Result 返回。
/* Copyright 2020 Google LLC.
SPDX-License-Identifier: Apache-2.0 */
override suspend fun doWork(): Result {
try {
// 要执行的代码
return Result.success()} catch (throwable: Throwable) {
// 进行清理并输入
return Result.failure()}
}
在 doWork() 中,您也须要告知 WorkManager 该工作应该在前台服务中立刻执行。
为此,您须要创立一个 ForegroundInfo 对象作为 setForeground() 的参数。ForegroundInfo 须要两个参数,一个是 Notification ID,另一个是将要被显示的 Notification。
当约束条件满足时,下列信息可用于创立和运行前台服务。
创立 ForegroundInfo
正确创立 ForegroundInfo 只需如下三步:
- 创立一个 Notification
- 创立一个 Notification Channel
- 将告诉引入 ForegroundInfo
在下列代码中,createForegroundInfo() 调用 createForegroundInfo(),createNotification()
函数会对 notification 进行填充并创立相应的 channel。
/* Copyright 2020 Google LLC.
SPDX-License-Identifier: Apache-2.0 */
/**
* 为前台服务运行的 Worker 创立 ForegroundInfo
*/
private fun createForegroundInfo(): ForegroundInfo {
// 每一个 Notification 须要应用不同的 id
val notificationId = 1
return ForegroundInfo(notificationId, createNotification())
}
/**
* 为前台服务运行工作创立 Notification 和所需的 channel (Andrid O 版本以上)
*/
private fun createNotification(): Notification {
//PendingIntent 可用来勾销 Worker
val intent = WorkManager.getInstance(context).createCancelPendingIntent(id)
val builder = Builder(context, channelId)
.setContentTitle(title)
.setTicker(title)
.setSmallIcon(R.drawable.baseline_gradient)
.setOngoing(true)
.addAction(drawable.ic_delete, cancel, intent)
if (VERSION.SDK_INT >= VERSION_CODES.O) {createNotificationChannel(channelId, name).also {builder.setChannelId(it.id)
}
}
return builder.build()}
/**
* 为 Android O 及以上版本的设施创立所需的 notification channel
*/
@TargetApi(VERSION_CODES.O)
private fun createNotificationChannel(
channelId: String,
name: String
): NotificationChannel {
return NotificationChannel(channelId, name, NotificationManager.IMPORTANCE_LOW).also { channel ->
notificationManager.createNotificationChannel(channel)
}
}
在前台服务中执行工作
当初把这些整合起来。咱们曾经实现了 doWork 函数,咱们能够调用 setForeground(),并且通过调用 createForegroundInfo() 来传递所需的信息。
/* Copyright 2020 Google LLC.
SPDX-License-Identifier: Apache-2.0 */
override suspend fun doWork(): Result {
try {setForeground(createForegroundInfo())
// 须要执行的代码
return Result.success(workDataOf(KEY_RESULT to result))
} catch (throwable: Throwable) {
// 进行清理并且输入日志
return Result.failure()}
}
⚠️⚠️⚠️
在长时间运行工作开始之前,先调用 setForeground()。
否则在 setForeground() 被调用之前,您的 Worker 将会被视为非前台服务,这样可能会导致这个工作被勾销或引起其余不心愿呈现的后果。
⚠️⚠️⚠️
下一步
当初大家曾经晓得何时以及如何利用长时间运行的 worker 了,那么能够进行下一步,开始在利用中实现它们。获取更多相干信息,请参阅以下资源:
在 GitHub 中查看 WorkManager 示例代码:
在前台服务中执行工作的代码,请查阅:
- BaseFilterWorker 类
- 提交记录
对于长时间运行 worker 和前台服务的具体指南,以及主题更多信息,请查阅:
- WorkManager 的高级指南|反对长时间运行的工作器
- 后盾解决指南
- Android 上的 Kotlin 协程
WorkManager 系列文章助您理解 WorkManager 从根底到高级的各项个性:
- Android Jetpack WorkManager | Android 中文教学视频
- WorkManager 在 Kotlin 中的实际
- WorkManager: 周期性工作
- 自定义 WorkManager —— 根底概念
- 应用 Dagger 自定义 WorkManager
Google IssueTracker 提交所遇到的任何问题,这将帮忙咱们第一工夫优化个性和修复破绽。