当前位置:网站首页>WorkManager学习一
WorkManager学习一
2022-07-05 09:49:00 【Mr_Tony】
文章目录
一、前言
目前执行长期的后台任务时候,官方推荐使用WorkManager来处理后台任务,这里对WorkManager进行一个简单的记录。WorkManager主要可以执行以下几种任务
二、添加依赖
dependencies {
val work_version = "2.7.1"
// (Java only)
implementation("androidx.work:work-runtime:$work_version")
// Kotlin + coroutines
implementation("androidx.work:work-runtime-ktx:$work_version")
// optional - RxJava2 support
implementation("androidx.work:work-rxjava2:$work_version")
// optional - GCMNetworkManager support
implementation("androidx.work:work-gcm:$work_version")
// optional - Test helpers
androidTestImplementation("androidx.work:work-testing:$work_version")
// optional - Multiprocess support
implementation "androidx.work:work-multiprocess:$work_version"
}
三、简单示例
一个WorkManager需要三部分组成。定义一个Work,创建一个WorkRequest,提交给WorkManager进行执行。以下是一个简单的一次性任务的示例。
WorkTest.kt
class WorkTest(val appContext: Context, workerParams: WorkerParameters): Worker(appContext, workerParams) {
override fun doWork(): Result {
Log.e("YM--->","后台任务执行中,任务线程:${
Thread.currentThread().id}-->线程名字:${
Thread.currentThread().name}")
return Result.success()
}
}
以下是两种创建WorkRequest的方式,一种复杂的,一种简单的,根据情况选择一种实现。
private fun initWork() {
// val uploadWorkRequest: WorkRequest = //复杂的构建器方式
// OneTimeWorkRequestBuilder<WorkTest>()
// .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)//设置加急任务
// .build()
val uploadWorkRequest: WorkRequest = OneTimeWorkRequest.from(WorkTest::class.java)//简单方式
WorkManager
.getInstance(this)
.enqueue(periodicWorkRequest)
}
使用WorkManager进行执行
WorkManager
.getInstance(this)
.enqueue(periodicWorkRequest)
四、定期任务
定期任务可以多次执行一个任务。以下是创建方式
val saveRequest =
PeriodicWorkRequestBuilder<WorkTest>(1, TimeUnit.HOURS)
// Additional configuration
.build()
需要注意下时间,如果时间小于15分钟,则会按照十五分钟进行计算,如果大于十五分钟则按照实际时间计算。
假设想要定义一个灵活的时间段,比如最后十五分钟执行任务,可以使用以下方式
val myUploadWork = PeriodicWorkRequestBuilder<SaveImageToFileWorker>(
1, TimeUnit.HOURS, // repeatInterval (the period cycle)
15, TimeUnit.MINUTES) // flexInterval
.build()
在创建 PeriodicWorkRequest 时传递 flexInterval 以及 repeatInterval。灵活时间段从 repeatInterval - flexInterval 开始,一直到间隔结束。
重复间隔必须大于或等于 PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS,而灵活间隔必须大于或等于 PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS。
五、工作约束
这里参考官方网站:
约束可确保将工作延迟到满足最佳条件时运行。以下约束适用于 WorkManager。
NetworkType 约束运行工作所需的网络类型。例如 Wi-Fi ( [UNMETERED](https://developer.android.google.cn/reference/androidx/work/NetworkType?hl=zh-cn#UNMETERED))。BatteryNotLow 如果设置为 true,那么当设备处于“电量不足模式”时,工作不会运行。 RequiresCharging 如果设置为 true,那么工作只能在设备充电时运行。 DeviceIdle 如果设置为 true,则要求用户的设备必须处于空闲状态,才能运行工作。在运行批量操作时,此约束会非常有用;若是不用此约束,批量操作可能会降低用户设备上正在积极运行的其他应用的性能。 StorageNotLow 如果设置为 true,那么当用户设备上的存储空间不足时,工作不会运行。 如需创建一组约束并将其与某项工作相关联,请使用一个
Contraints.Builder()创建Constraints实例,并将该实例分配给WorkRequest.Builder()。例如,以下代码会构建了一个工作请求,该工作请求仅在用户设备正在充电且连接到 Wi-Fi 网络时才会运行:
val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.UNMETERED) .setRequiresCharging(true) .build() val myWorkRequest: WorkRequest = OneTimeWorkRequestBuilder<MyWork>() .setConstraints(constraints) .build()如果指定了多个约束,工作将仅在满足所有约束时才会运行。
如果在工作运行时不再满足某个约束,WorkManager 将停止工作器。系统将在满足所有约束后重试工作。
六、延迟工作
上面的任务默认来说会立即执行,倘若想要延迟执行的话可以采取以下方式:
val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
.setInitialDelay(10, TimeUnit.MINUTES)
.build()
需要注意的是定时任务,只有首次会延迟。
七、 重试和重试策略
倘若任务执行失败,想要进行重试,可以使用该方式。重试有两个参数构成:重试时间和重试策略。重试时间是指每次重试前的等待时间,最短10s或者 MIN_BACKOFF_MILLIS。重试策略则是指后续的重试时间以何种方式增涨,有两个参数,一个是线性增涨LINEAR,一个是指数增长EXPONENTIAL。不能设置每次固定的时间。如果使用重试的话,需要在定义 Worker时候返回Result.retry(),不能返回Result.success()。以下是参考代码:
val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
.setBackoffCriteria(
BackoffPolicy.LINEAR,
OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
TimeUnit.MILLISECONDS)
.build()
八、工作标识
以下参考官网网站:
每个工作请求都可以设置一个唯一标识符,该标识符可用于在以后标识该工作,以便取消工作或观察其进度。
如果有一组在逻辑上相关的工作,对这些工作项进行标记可能也会很有帮助。通过标记,您一起处理一组工作请求。
例如,WorkManager.cancelAllWorkByTag(String) 会取消带有特定标记的所有工作请求,WorkManager.getWorkInfosByTag(String)会返回一个 WorkInfo 对象列表,该列表可用于确定当前工作状态。
以下代码展示了如何向工作添加“cleanup”标记:
val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>() .addTag("cleanup") .build()最后,可以向单个工作请求添加多个标记。这些标记在内部以一组字符串的形式进行存储。您可以使用 WorkInfo.getTags() 获取与
WorkRequest关联的标记集。从
Worker类中,您可以通过 ListenableWorker.getTags() 检索其标记集。
九、传递参数
有些工作需要传递一些参数。可以使用以下的方式, 示例代码如下:
// Define the Worker requiring input
class UploadWork(appContext: Context, workerParams: WorkerParameters)
: Worker(appContext, workerParams) {
override fun doWork(): Result {
val imageUriInput =
inputData.getString("IMAGE_URI") ?: return Result.failure()
uploadFile(imageUriInput)
return Result.success()
}
...
}
// Create a WorkRequest for your Worker and sending it input
val myUploadWork = OneTimeWorkRequestBuilder<UploadWork>()
.setInputData(workDataOf(
"IMAGE_URI" to "http://..."
))
.build()
十、加急任务
加急任务据官网说是对那些需要立即执行的任务,比如添加订阅,支付账单,发送消息。但是初步接触,没有发现和其它任务的区别。可能是在WorkManager有很多任务时候,会导致任务排队,加急任务可以将任务插入到队前进行加快执行。
加急任务是在WorkManager2.7的时候添加的。并且可能在Android12之前的版本上运行前台服务。所以在一定程度上限制了其使用场景。
以下是引用内容
在 Android 12 之前,工作器中的
getForegroundInfoAsync()和getForegroundInfo()方法可让 WorkManager 在您调用setExpedited()时显示通知。如果您想要请求任务作为加急作业运行,则所有的 ListenableWorker 都必须实现
getForegroundInfo方法。注意:如果未能实现对应的
getForegroundInfo方法,那么在旧版平台上调用setExpedited时,可能会导致运行时崩溃。以 Android 12 或更高版本为目标平台时,前台服务仍然可通过对应的
setForeground方法使用。注意:
setForeground()可能会在 Android 12 上抛出运行时异常,并且在启动受到限制时可能会抛出异常。工作器
工作器不知道自身所执行的工作是否已加急。不过,在某些版本的 Android 上,如果
WorkRequest被加急,工作器可以显示通知。为此,WorkManager 提供了
getForegroundInfoAsync()方法,您必须实现该方法,让 WorkManager 在必要时显示通知,以便启动ForegroundService。CoroutineWorker
如果您使用
CoroutineWorker,则必须实现getForegroundInfo()。然后,在doWork()内将其传递给setForeground()。这样做会在 Android 12 之前的版本中创建通知。请参考以下示例:
class ExpeditedWorker(appContext: Context, workerParams: WorkerParameters): CoroutineWorker(appContext, workerParams) { override suspend fun getForegroundInfo(): ForegroundInfo { return ForegroundInfo( NOTIFICATION_ID, createNotification() ) } override suspend fun doWork(): Result { TODO() } private fun createNotification() : Notification { TODO() }}注意:您应该将
setForeground()封装在try/catch块中,以捕获可能出现的IllegalStateException。如果您的应用此时无法在前台运行,便可能会发生这类异常。在 Android 12 及更高版本中,您可以使用更详细的ForegroundServiceStartNotAllowedException。配额政策
您可以控制当应用达到其执行配额时加急工作会发生什么情况。如需继续,您可以传递
setExpedited():
OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST,这会导致作业作为普通工作请求运行。上述代码段演示了此操作。OutOfQuotaPolicy.DROP_WORK_REQUEST,这会在配额不足时导致请求取消。示例应用
如需查看关于 WorkManager 2.7.0 如何使用加急工作的完整示例,请查看 GitHub 上的 WorkManagerSample。
延迟加急工作
系统会尝试在调用指定的加急作业后,尽快执行该作业。不过,与其他类型的作业一样,系统可能会延迟启动新的加急工作,如在以下情况下:
- 负载:系统负载过高,当有过多作业已在运行或者当系统内存不足时,就会发生这种情况。
- 配额:已超出加急作业配额限制。加急工作使用基于应用待机存储分区的配额系统,并限制滚动时间窗口中的最大执行时间。用于加急工作的配额比用于其他类型的后台作业的配额限制性更强。
需要注意的是,上文继承的Work类,是ListenableWorker的子类,所以依然要重写getForegroundInfoAsync()函数。
十一、参考链接
边栏推荐
- 历史上的今天:第一本电子书问世;磁条卡的发明者出生;掌上电脑先驱诞生...
- MySQL数字类型学习笔记
- Wechat applet - simple diet recommendation (4)
- What is the origin of the domain knowledge network that drives the new idea of manufacturing industry upgrading?
- Swift uses userdefaults and codable to save an array of class objects or structure instances
- RMS TO EAP通过MQTT简单实现
- 天龙八部TLBB系列 - 单体技能群伤
- View Slide
- Interview: is bitmap pixel memory allocated in heap memory or native
- 【系统设计】指标监控和告警系统
猜你喜欢

自动化规范检查软件如何发展而来?

Comment obtenir le temps STW du GC (collecteur d'ordures)?

Six simple cases of QT

学习笔记5--高精地图解决方案

Swift tableview style (I) system basic

Those who are good at using soldiers, hide in the invisible, and explain the best promotional value works in depth in 90 minutes

【小技巧】獲取matlab中cdfplot函數的x軸,y軸的數值

Redis如何实现多可用区?

ArcGIS Pro 创建要素
![[论文阅读] CKAN: Collaborative Knowledge-aware Atentive Network for Recommender Systems](/img/6c/5b14f47503033bc2c85a259a968d94.png)
[论文阅读] CKAN: Collaborative Knowledge-aware Atentive Network for Recommender Systems
随机推荐
ArcGIS Pro creating features
橫向滾動的RecycleView一屏顯示五個半,低於五個平均分布
程序员搞开源,读什么书最合适?
学习笔记4--高精度地图关键技术(下)
(1) Complete the new construction of station in Niagara vykon N4 supervisor 4.8 software
天龙八部TLBB系列 - 关于包裹掉落的物品
Comment obtenir le temps STW du GC (collecteur d'ordures)?
一种用于干式脑电图的高密度256通道电极帽
View Slide
Kotlin compose and native nesting
Cerebral cortex: directed brain connection recognition widespread functional network abnormalities in Parkinson's disease
MySQL digital type learning notes
Applet image height adaptation and setting text line height
最全是一次I2C总结
To bring Euler's innovation to the world, SUSE should be the guide
让AI替企业做复杂决策真的靠谱吗?参与直播,斯坦福博士来分享他的选择|量子位·视点...
《天天数学》连载58:二月二十七日
CSDN always jumps to other positions when editing articles_ CSDN sends articles without moving the mouse
Generics, generic defects and application scenarios that 90% of people don't understand
Swift uses userdefaults and codable to save an array of class objects or structure instances