Android Jetpack组件之WorkManager后台任务管理的介绍与使用(一)

news/2024/4/25 9:53:59/文章来源:https://blog.csdn.net/qq36246172/article/details/128952263

一、介绍

Jetpack?

        我们经常看到,似乎很高端,其实这个就是一个名词,或者说是一种框架概念。

Jetpack 包含一系列 Android 库,它们都采用最佳做法并在 Android 应用中提供向后兼容性。

Jetpack 应用架构指南概述了构建 Android 应用时要考虑的最佳做法和推荐架构。

最终就是Android平台的一个介绍,有些新人看到又以为是什么平台,甚至一些招聘会写需要了解Room数据,Jetpack组件,其实我们现在好多已在使用了,但是非专业人会不停提jetpack导致一些人在理解的时候被吓到了。

JetPack组件已全部支出androidX,如果你的项目没有升级到AndroidX,请先升级到AdnroidX。

利用 Jetpack

Jetpack 库可以单独使用,也可以组合使用,以满足应用的不同需求。

  • WorkManager - 满足您的后台调度需求。
  • Room - 实现数据存储持久性。
  • Navigation - 管理应用导航流程。
  • CameraX - 满足相机应用需求。
  • 请参阅所有 Jetpack 库的概览。

二、WorkManager

        WorkManager 是适合用于持久性工作的推荐解决方案。如果工作始终要通过应用重启和系统重新启动来调度,便是持久性的工作。由于大多数后台处理操作都是通过持久性工作完成的,因此 WorkManager 是适用于后台处理操作的主要推荐 API。

持久性工作的类型

WorkManager 可处理三种类型的持久性工作:

  • 立即执行:必须立即开始且很快就完成的任务,可以加急。
  • 长时间运行:运行时间可能较长(有可能超过 10 分钟)的任务。
  • 可延期执行:延期开始并且可以定期运行的预定任务。
持久性工作的类型

 

类型周期使用方式
立即一次性OneTimeWorkRequest 和 Worker

如需处理加急工作,请对 OneTimeWorkRequest 调用 setExpedited()

长期运行一次性或定期任意 WorkRequest 或 Worker。在工作器中调用 setForeground() 来处理通知。
可延期一次性或定期PeriodicWorkRequest 和 Worker

使用 WorkManager 保证工作可靠性

WorkManager 适用于需要可靠运行的工作,即使用户导航离开屏幕、退出应用或重启设备也不影响工作的执行。例如:

  • 向后端服务发送日志或分析数据。
  • 定期将应用数据与服务器同步。

WorkManager 不适用于那些可在应用进程结束时安全终止的进程内后台工作。它也并非对所有需要立即执行的工作都适用的通用解决方

三、接入

1、依赖库

//work
def  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 - Multiprocess support
implementation "androidx.work:work-multiprocess:$work_version"

由于国内应用,GCM可以不需要,因为这个GCM是google service,国内的手机不支持

2、接入

2.1 先定义一个worker

工作使用 Worker 类定义。doWork() 方法在 WorkManager 提供的后台线程上异步运行

class MyWorks(context: Context,workerParameters: WorkerParameters) : Worker(context, workerParameters) {@SuppressLint("RestrictedApi")override fun doWork(): Result {//后台异步执行var success=Result.Success()var error=Result.failure()var retry=Result.retry()return success}
}

doWokr():是我们需要执行的方法体,需要异步执行,都将在这边执行。最后将执行的结果返回即可Result。

从 doWork() 返回的 Result 会通知 WorkManager 服务工作是否成功,以及工作失败时是否应重试工作。

  • Result.success():工作成功完成。
  • Result.failure():工作失败。
  • Result.retry():工作失败,应根据其重试在其他时间尝试。
public Success(@NonNull Data outputData) {super();mOutputData = outputData;
}

创建 WorkRequest

        定义工作后,必须使用 WorkManager 服务进行调度该工作才能运行。对于如何调度工作,WorkManager 提供了很大的灵活性。您可以将其安排为在某段时间内定期运行,也可以将其安排为仅运行一次。

        不论您选择以何种方式调度工作,请始终使用 WorkRequest。Worker 定义工作单元,WorkRequest(及其子类)则定义工作运行方式和时间。在最简单的情况下,您可以使用 OneTimeWorkRequest

提交work执行:

val workRequest:WorkRequest=OneTimeWorkRequestBuilder<MyWorks>().build()
WorkManager.getInstance(application).enqueue(workRequest)

这种是一次性调度。

也可以通过from来创建request:

val workRequest=  OneTimeWorkRequest.from(MyWorks::class.java)

这种构建也只能构建简单的

复杂构建:

复杂的构建需要通过OneTimeWorkRequestBuilder来构建

val build=OneTimeWorkRequestBuilder<MyWorks>()
通过build来设置加载机制和延迟等

调度加急

        WorkManager 2.7.0 引入了加急工作的概念。这使 WorkManager 能够执行重要工作,同时使系统能够更好地控制对资源的访问权限。

加急工作具有以下特征:

  • 重要性:加急工作适用于对用户很重要或由用户启动的任务。
  • 速度:加急工作最适合那些立即启动并在几分钟内完成的简短任务。
  • 配额:限制前台执行时间的系统级配额决定了加急作业是否可以启动。
  • 电源管理:电源管理限制(如省电模式和低电耗模式)不太可能影响加急工作。
  • 延迟时间:系统立即执行加急工作,前提是系统的当前工作负载允许执行此操作。这意味着这些工作对延迟时间较为敏感,不能安排到以后执行。

执行加急

从 WorkManager 2.7 开始,您的应用可以调用 setExpedited() 来声明 WorkRequest 应该使用加急作业,以尽可能快的速度运行。以下代码段展示了关于如何使用 setExpedited() 的示例

val request = OneTimeWorkRequestBuilder().setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST).build()

向后兼容性和前台服务

为了保持加急作业的向后兼容性,WorkManager 可能会在 Android 12 之前版本的平台上运行前台服务。前台服务可以向用户显示通知。

在 Android 12 之前,工作器中的 getForegroundInfoAsync() 和 getForegroundInfo() 方法可让 WorkManager 在您调用 setExpedited() 时显示通知。

如果您想要请求任务作为加急作业运行,则所有的 ListenableWorker 都必须实现 getForegroundInfo 方法

override fun getForegroundInfoAsync(): ListenableFuture<ForegroundInfo> {return super.getForegroundInfoAsync()
}

CoroutineWorker:

        如果您使用 CoroutineWorker,则必须实现 getForegroundInfo()。然后,在 doWork() 内将其传递给 setForeground()。这样做会在 Android 12 之前的版本中创建通知

    override suspend fun getForegroundInfo(): ForegroundInfo {val id = Random.nextInt(0, Int.MAX_VALUE)return ForegroundInfo(id, getNotion())}private fun getNotion(): Notification {val notification = Notification()return notification;}

配额政策:

  • OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST:
           这会导致作业作为普通工作请求运行。上述代码段演示了此操作。
     
  • OutOfQuotaPolicy.DROP_WORK_REQUEST
    这会在配额不足时导致请求取消。

定期调度

您的应用有时可能需要定期运行某些工作,使用 PeriodicWorkRequest 创建定期执行的 WorkRequest

val request=PeriodicWorkRequestBuilder<MyWorks>(5,TimeUnit.MILLISECONDS)

解释:

        时间间隔定义为两次重复执行之间的最短时间。工作器的确切执行时间取决于您在 WorkRequest 对象中设置的约束以及系统执行的优化。

val reques1=PeriodicWorkRequestBuilder<MyWorks>(5,TimeUnit.HOURS,15,TimeUnit.MINUTES)

重复间隔必须大于或等于 PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS,而灵活间隔必须大于或等于 PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS

    /*** The minimum interval duration for {@link PeriodicWorkRequest} (in milliseconds).*/@SuppressLint("MinMaxConstant")public static final long MIN_PERIODIC_INTERVAL_MILLIS = 15 * 60 * 1000L; // 15 minutes./*** The minimum flex duration for {@link PeriodicWorkRequest} (in milliseconds).*/@SuppressLint("MinMaxConstant")public static final long MIN_PERIODIC_FLEX_MILLIS = 5 * 60 * 1000L; // 5 minutes.

repeatInterval :重复的时间值
flexInterval:第二个时间值,

约束

约束可确保将工作延迟到满足最佳条件时运行。以下约束适用于 WorkManager

NetworkType约束运行工作所需的网络类型。例如 Wi-Fi (UNMETERED)。
BatteryNotLow如果设置为 true,那么当设备处于“电量不足模式”时,工作不会运行。
RequiresCharging如果设置为 true,那么工作只能在设备充电时运行。
DeviceIdle如果设置为 true,则要求用户的设备必须处于空闲状态,才能运行工作。在运行批量操作时,此约束会非常有用;若是不用此约束,批量操作可能会降低用户设备上正在积极运行的其他应用的性能。
StorageNotLow

如果设置为 true,那么当用户设备上的存储空间不足时,工作不会运行。

如需创建一组约束并将其与某项工作相关联,请使用一个 Contraints.Builder() 创建 Constraints 实例,并将该实例分配给 WorkRequest.Builder()

       val constraints = Constraints.Builder().setRequiredNetworkType(NetworkType.UNMETERED).setRequiresCharging(true).build()val myWorkRequest: WorkRequest =OneTimeWorkRequestBuilder<MyWorks>().setConstraints(constraints).build()

如果指定了多个约束,工作将仅在满足所有约束时才会运行。

如果在工作运行时不再满足某个约束,WorkManager 将停止工作器。系统将在满足所有约束后重试工作。

延迟:

如果您不希望工作立即运行,可以将工作指定为在经过一段最短初始延迟时间后再启动

al myWorkRequest = OneTimeWorkRequestBuilder<MyWork>().setInitialDelay(10, TimeUnit.MINUTES).build()

这个延迟和handler的延迟机制是一样使用。PeriodicWorkRequest 设置初始延迟时间,在这种情况下,定期工作只有首次运行时会延迟。

重试和退避

如果您需要让 WorkManager 重试工作,可以从工作器返回 Result.retry()。然后,系统将根据退避延迟时间和退避政策重新调度工作。

  • 退避延迟时间指定了首次尝试后重试工作前的最短等待时间。此值不能超过 10 秒(或 MIN_BACKOFF_MILLIS)。

  • 退避政策定义了在后续重试过程中,退避延迟时间随时间以怎样的方式增长。WorkManager 支持 2 个退避政策,即 LINEAR 和 EXPONENTIAL

val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>().setBackoffCriteria(BackoffPolicy.LINEAR,OneTimeWorkRequest.MIN_BACKOFF_MILLIS,TimeUnit.MILLISECONDS).build()

最短退避延迟时间设置为允许的最小值,即 10 秒。由于政策为 LINEAR,每次尝试重试时,重试间隔都会增加约 10 秒。例如,第一次运行以 Result.retry() 结束并在 10 秒后重试;然后,如果工作在后续尝试后继续返回 Result.retry(),那么接下来会在 20 秒、30 秒、40 秒后重试,以此类推。如果退避政策设置为 EXPONENTIAL,那么重试时长序列将接近 20、40、80 秒,以此类推。

标记

在request的对象中,都支持setTag,方便我们在获取对象时,可以通标记值来获取。这个类似线程池获取某个线程一样,只要我们知道线程的名字,就能准确的找到

val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>().addTag("cleanup").build()

数据绑定:

在处理异步操作时,必然和数据打交道,如何传递数据呢?通过Data来传递

通过request的setInputData来完成,我们在override fun doWork(): Result{}中,获取到

override fun doWork(): Result {//数据集合var data= inputData;return retry
}

同样,也可以将结果通过Resukt返回出去。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_255855.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记录复现一下第一次awd

前言 之前没打过awd&#xff0c;这次学长组织了一场awd娱乐赛&#xff0c;两个web一个pwn&#xff0c;还有一个黑盒&#xff0c;只会web&#xff0c;第一次啥也不会瞎打&#xff0c;被打烂了&#xff0c;不会写脚本&#xff0c;手交flag的感觉真“不错”&#xff0c;感觉awd还…

I/O多路复用

基础概念 Socket 套接字。百科&#xff1a;对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。 例子1&#xff1a;客户端将数据通过网线发送到服务端&#xff0c;客户端发送数据需要一个出口&#xff0c;服务端接收数据需要一个入口&#xff0c;这两个“口子”就是…

开发技术-Java switch case 的简单用法

文章目录1. integral-selector2. case3. break4. default5. 总结最近开发写 switch 发现有的技术点还没有掌握&#xff0c;在此做个记录。ON JAVA 中文版中&#xff0c;关于 switch 的描述为&#xff1a; switch 有时也被划归为一种选择语句。根据整数表达式的值&#xff0c;s…

数据挖掘,计算机网络、操作系统刷题笔记47

数据挖掘&#xff0c;计算机网络、操作系统刷题笔记47 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;orac…

FFmpeg集成qsv的编译安装

文章目录FFmpeg集成qsv的编译安装一、参考二、编译安装流程1. LibVA 和 Media-Driver 的安装2. Intel Media SDK 编译3. ffmpeg的编译安装4. 验证安装FFmpeg集成qsv的编译安装 一、参考 Ubuntu20.04 ffmpeg添加 Intel核显QSV加速支持 视频和视频帧&#xff1a;Intel GPU&…

持续集成Jenkins (四)Jenkins+git+maven项目构建、自动化部署

GIT配置1.1 前言&#xff1a;需要安装 git 客户端.yum install git1.2 Jenkins 配置插件 Git 在仪表盘选择Manage Jenkins>>Plugin Manager>>进入如下页面&#xff0c;可以选择可选的插件&#xff0c;安装完成后的插件在installed里面可以看到&#xff0c;我这里已…

Conda安装到虚拟环境中的包在pycharm中不显示--pip下载的包都到了base环境中-Ubuntu20.04

问题 今天刚装了一个Ubuntu20.04系统&#xff0c;安装完Anaconda&#xff0c;虚拟环境的包也都下载好了&#xff0c;结果在pycharm中配置完解释器后&#xff0c;只有几个基础的包&#xff0c;切换到base环境后发现&#xff0c;这些包都被下载到了base环境中。 在网上查了各种…

安装PhpStorm2020.3

1、卸载旧软件 如果已安装软件&#xff0c;先打开文件安装目录&#xff0c;找到Uninstall.exe点击卸载 删除.jetbrains目录 点击软件“PhpStorm-2020.3.exe”安装 打开软件 打开一个新建的空文件夹&#xff0c;预加载 将BetterIntelliJ.zip拖动到idea的编辑区域 然后…

我们的微服务中为什么需要网关?

说起 Spring Cloud Gateway 的使用场景&#xff0c;我相信很多小伙伴都能够脱口而出认证二字&#xff0c;确实&#xff0c;在网关中完成认证操作&#xff0c;确实是 Gateway 的重要使用场景之一&#xff0c;然而并不是唯一的使用场景。在微服务中使用网关的好处可太多了&#x…

nodejs基于vue的饭店点餐外卖平台网站

本系统主要实现了管理员&#xff1a;首页、个人中心、用户管理、菜品分类管理、菜品信息管理、菜品评价管理、系统管理、订单管理,用户&#xff1a;首页、个人中心、菜品评价管理、我的收藏管理、订单管理,前台首页&#xff1a;首页、菜品信息、菜品资讯、个人中心、后台管理、…

C++——继承那些事儿你真的知道吗?

目录1.继承的概念及定义1.1继承的概念1.2 继承定义1.2.1定义格式1.2.2继承关系和访问限定符1.2.3继承基类成员访问方式的变化2.父类和子类对象赋值转换3.继承中的作用域4.派生类的默认成员函数5.继承与友元6. 继承与静态成员7.复杂的菱形继承及菱形虚拟继承如何解决数据冗余和二…

基于深度学习的安全帽监管系统

摘 要 安全生产管理是建筑、重工业等高危企业发展的重要方针,安全帽在施工生产环境中对人员头部防护起着关键作用,因此加强安全帽佩戴监管十分必要。近年来,基于图像视觉的安全帽佩戴监测方法成为了企业实施管理的主要手段,如何提高安全帽佩戴检测精度和检测速度是应用的关键难…

【C++】 类和对象 (下)

文章目录&#x1f4d5;再谈构造函数1. 构造函数体赋值2. 初始化列表3. explicit 关键字&#x1f4d5;static 成员1. 概念2. static 成员变量3. static 成员函数&#x1f4d5; 友元1. 友元函数2. 友元类&#x1f4d5;内部类&#x1f4d5;编译器优化&#x1f4d5;再谈构造函数 1…

C# 引用DLL 静态字段和非静态字段

再讲一下如何引用dll动态链接库&#xff1a;右键项目----添加 --项目引用----选择你要添加的dll即可。在依赖项这里就可以看到。再在要用的项目那里using一下这个dll的命名空间&#xff1a;using 生成dll;然后就可以使用以下所说的两种方法去调用dll里的函数了。切记&#xff0…

canal 使用详解

第1章 Canal 简介canal [kənl]&#xff0c;译意为水道/管道/沟渠&#xff0c;主要用途是基于 MySQL 数据库增量日志解析&#xff0c;提供增量数据订阅和消费工作原理canal 模拟 MySQL slave 的交互协议&#xff0c;伪装自己为 MySQL slave &#xff0c;向 MySQL master 发送 d…

fastadmin后台表单文字过长,限制显示,鼠标悬停显示全部

问题&#xff1a;显示文字区域过长&#xff0c;影响用户体验感 解决措施&#xff1a; 特别注意&#xff1a; return "<span styledisplay: block;overflow: hidden;text-overflow: ellipsis;white-space: nowrap; title" row.contents ">" value …

【物联网平台选型】葵花宝典:盘点开源、SaaS及通用型平台的优劣势和选型适配

随着工业物联网领域和智慧物联领域的发展&#xff0c;大大小小的物联项目和物联场景需求层出不穷&#xff0c;物联网平台作为技术底座型软件&#xff0c;是不可或缺的项目地基。 市场需求下&#xff0c;物联网平台提供商越来越多&#xff0c;“打地基”的方式大体分为开源平台、…

内核数据结构-XArray

内核数据结构-XArrayXArray简介XArray 基本数据结构Xarray结构图API介绍Xarray锁参考链接XArray简介 XArray是一种抽象数据类型&#xff0c;类似于一个大的指针数组&#xff0c;它满足了许多与哈希或常规可调整大小数组相同的需求。由于 xarray 中的数据都是指针&#xff0c;使…

以太网知识-GMII / RGMII接口

今天和海翎光电的小编一起分析MII/RMII/SMII&#xff0c;以及GMII/RGMII/SGMII接口的信号定义&#xff0c;及相关知识&#xff0c;同时小编也对RJ-45接口进行了总结&#xff0c;分析了在10/100模式下和1000M模式下的连接方法。GMII 接口分析GMII接口提供了8位数据通道&#xff…

shell条件测试

文章目录三、shell条件测试3.1条件测试的基本语法3.2 文件测试表达式3.3字符串测试表达式3.4 整数测试表达式3.5 逻辑操作符三、shell条件测试 为了能够正确处理Shell程序运行过程中遇到的各种情况&#xff0c;Linux Shell提供了一组测试运算符。通过这些运算符&#xff0c;Sh…