当前位置: 首页 > ds >正文

WorkManager

WorkManager

作用

管理后台任务,平衡用电量和用户体验

1.针对的是不需要及时完成的任务。

例如,发送应用程序日志、同步应用程序数据、备份用户数据等,站在业务需求的角度,这些任务都不需要立即完成。如果我们自己来管理这些任务,逻辑可能会非常复杂,若API 使用不恰当,可能会消耗大量电量。

  1. 保证任务一定会被执行。

WorkManager 能保证任务一定会被执行,即使应用程序当前不在运行中,甚至在设备重启过后,任务仍然会在适当的时刻被执行。这是因为 WorkManager 有 自己的数据库,关于任务的所有信息和数据都保存在该数据库中。因此,只要任务交给了 WorkManager, 哪怕应用程序彻底退出,或者设备被重新启动, WorkManager 依然能够保证完成你交给它的任务。

  1. 兼容范围广

WorkManager 最低能兼容API Level 14,并且不需要你的设备安装Google Play Services 。因此,不用过于担心兼容性问题,因为API Level 14已经能够兼容几乎 100%的设备。

WorkManager 能依据设备的情况,选择不同的执行方案。在API Level 23以上 的设备中,通过 JobScheduler 完成任务;在 API Level 23 以下的设备中,通过 AlarmManager 和 Broadcast Receivers 组合来完成任务。但无论采用哪种方案,任 务最终都是交由Executor 来执行的

使用

使用Worker类定义任务

假设要实现将日志上传到服务器的需求。新建一个名为 UploadLogWorker 的 类,该类继承自Worker 类,重写doWork()方法

doWork()方法有3种类型的返回值。

● 若执行成功,则返回Result.success()。

● 若执行失败 , 则返回Result.failure()。

● 若需要重新执行,则返回Result.retry()。

使用WorkReques配置任务

  1. 设置任务触发条件。

    Constraints constraints = new Constraints.Builder().setRequiresCharging(true).setRequiredNetworkType(NetworkType.CONNECTED) 					   					.setRequiresBatteryNotLow(true).build();
    
  2. 将任务触发条件设置到WorkRequest。

WorkRequest 是一个抽象类,它有两种实现方式——OneTimeWorkRequest 和 PeriodicWorkRequest, 分别对应的是一次性任务和周期性任务,周期性任务的间隔时间不能少于15分钟。

假设没有设置触发条件,或者所设置的触发条件此刻符合系统的执行要求, 此时,系统有可能会立刻执行该任务。但如果你希望能够延迟任务的执行,那么 可 以 通 过setInitialDelay() 方法 , 对任 务 进 行 延 后

OneTimeWorkRequest uploadWorkRequest = new OneTimeWorkRequest.Builder(UploadLogWorker.class)       .setConstraints(constraints).setInitialDelay(10,TimeUnit.SECONDS).build();

3.假如 Worker 线程的执行出现了异常,如服务器宕机。你可能希望过一段时间 后,重试该任务。那么可以在Worker 的 doWork() 方法中返回Result.retry(), 系 统 会有默认的指数退避策略来帮你重试任务,也可以通过setBackoffCriteria() 方法来 自定义指数退避策略 。

OneTimeWorkRequest  uploadWorkRequest =new OneTimeWorkRequest.Builder(UploadLogWorker.class)//设置指数退避算法.setBackoffCriteria(BackoffPolicy.LINEAR,OneTimeWorkRequest.MIN_BACKOFF_MILLIS,TimeUnit.MILLISECONDS) .build();

4.设置 tag 标签后,你就可以通过该标签跟踪任务的状态:WorkManager.getWork InfosByTagLiveData(String tag); 也 可 以 取 消 任 务 :WorkManager.cancelAll WorkByTag(String tag)。

OneTimeWorkRequest uploadWorkRequest  =new OneTimeWorkRequest.Builder(UploadLogWorker.class).addTag("UploadTag").build();

5.将任务提交给系统

WorkManager.getInstance(this).enqueue(uploadWorkRequest);

观察任务状态

任务在提交给系统后,可以通过WorkInfo 获知任务的状态。WorkInfo 包含任 务的id 、tag 、Worker 对象传递过来的outputData, 以及任务当前的状态。有3种 方式可以得到WorkInfo 对象。

● WorkManager.getWorkInfosByTag()。

● WorkManager.getWorkInfoById()。

● WorkManager.getWorkInfosForUnique Work()。

如果希望实时获知任务的状态,这3个方法还有对应的LiveData 方法。

● WorkManager.getWorkInfosByTagLiveData()。

● WorkManager.getWorkInfoByIdLiveData()。

● WorkManager.getWorkInfosForUniqueWorkLiveData()。

WorkManager.getInstance(this).getWorkInfoByIdLiveData(uploadWorkRequest.getId()).observe(MainActivity.this,new Observer<WorkInfo>(){@Overridepublic void onChanged(WorkInfo workInfo){Log.d("onChanged()->","workInfo:"+workInfo);});

取消任务

与观察任务类似,我们也可以根据 id 或 tag 取消某个任务,或者取消所有的任务。

WorkManager.getInstance(MainActivity.this).cancelA11Work();

WorkManager 与Worker 之间的参数传递

WorkManager 通过 setInputData() 方法向 Worker 传递数据。数据的传递通过 Data 对象来完成。需要注意的是, Data 只能用于传递一些小的基本类型的数据, 且数据最大不能超过10KB。

Data inputData = new Data.Builder().putString("input_data","Hello World!").build();
OneTimeWorkRequest uploadworkRequest =new OneTimeworkRequest.Builder(UploadLogWorker.class).setInputData(inputData).build();

Worker 通 过getInputData() 方法接收数据,并在任务完成后,向WorkManager 返回数据 。

@Override
public Result dowork()
{
// 接收外面传递进来的数据
String  inputData = getInputData()·getString("input_data");
//任务执行完成后返回数据
Data  outputData = new Data.Builder().putString("output_data","Task Success!").build();
}

WorkManager 通过LiveData 得到从Worker 返回的数据。

WorkManager.getInstance(this)
.getWorkInfoByIdLiveData(uploadWorkRequest.getId())
.observe(MainActivity.this,new Observer<WorkInfo>()
{@Overridepublic void onChanged(WorkInfo workInfo){if(workInfo !=null  && workInfo.getState()==WorkInfo.State.SUCCEEDED){String outputData = workInfo.getOutputData().getString("output_data");}}
});

任务链

如果有一系列的任务需要按顺序执行,那么可以利用 WorkManager.begin With().then().then().…enqueue()的方式构建任务链。例如,在上传数据之前,可能需 要先对数据进行压缩。

WorkManager.getInstance(this)
.beginWith(compressWorkRequest) 
.then(uploadWorkRequest)
.enqueue();

假设有更复杂的任务链,那么还可以考虑使用 WorkContinuation.combine()方 法,将任务链组合起来使用。在下面的代码中,任务的执行顺序为A 、B 、

​ E

​ C 、D、

WorkContinuation	workContinuation1	= WorkManager.getInstance(this).beginWith(WorkRequestA).then(WorkRequestB);
WorkContinuation	workContinuation2	=WorkManager.getInstance(this).beginWith(WorkRequestC).then(WorkRequestD);
List<WorkContinuation>taskList=new	ArrayList<>();
taskList.add(workContinuation1);
taskList.add(workContinuation2);
WorkContinuation.combine(taskList)
.then(WorkRequestE) .enqueue();	

注意点

1.虽然 WorkManager 宣称,能够保证任务得到执行,在非 Android 原生 系统的真实设备中进行测试时发现,应用程序彻底退出与设备重新启动之后,任务都没有被再次执行

前面也提到 了 ,WorkManager 会根据系统的版本,决定采用 JobScheduler 或 AlarmManager + Broadcast Receivers来完成任务。问题在于,这些API 很可能会受 到非原生系统的影响。例如,某个非原生系统如果不允许AlarmManager 被主动唤 起,那么 WorkManager很可能无法在该系统上正常使用。

2.周期性任务的实际执行时间,与所设定的时间差别较大。并且在任务执行完成后WorkInfo 并不会收到 Success的通知。查阅相关资料后发现,Android认为Success 和 Failure 都属于“终止类”的通知。这意味着,若发出此类通知,则表明任务“彻底终止”, 而周期性任务是不会彻底终止的,它会一直执行下去。因此,在使用 LiveData 观 察周期性任务时,不会收到Success 这一类的通知

http://www.xdnf.cn/news/19446.html

相关文章:

  • BGP路由协议(四):工作原理
  • 银河麒麟Kylin系统安装各种板卡(反射内存卡、图像注入卡、串口卡等)步骤及解决方案
  • 微服务-ruoyi-cloud部署
  • 直流无刷电机2
  • 网络编程(4)
  • windows系统中安装zip版本mysql,配置环境
  • React学习教程,从入门到精通, ReactJS - 优点与缺点(5)
  • 线段树相关算法题(5)
  • LangGraph结构化输出详解:让智能体返回格式化数据
  • Midjourney绘画创作入门操作创作(广告创意与设计)
  • XHR 介绍及实践
  • 【Game-Infra】游戏开发的流程,游戏发布的打包与构建(硬件选型,SDK与操作系统,包体管理,弹性构建,构建调优)
  • 基于 GME-Qwen2-VL-7B 实现多模态语义检索方案
  • 人工智能学习:Python相关面试题
  • 零基础学C++,函数篇~
  • Visual Studio内置环境变量有哪些
  • MQTT 连接建立与断开流程详解(一)
  • Redission 实现延迟队列
  • Verilog 硬件描述语言自学——重温数电之典型组合逻辑电路
  • 基于 Spring Boot3 的ZKmall开源商城分层架构实践:打造高效可扩展的 Java 电商系统
  • 大语言模型的“可解释性”探究——李宏毅大模型2025第三讲笔记
  • Linux kernel 多核启动
  • Tomcat 企业级运维实战系列(六):综合项目实战:Java 前后端分离架构部署
  • 〔从零搭建〕数据中枢平台部署指南
  • 汽车加气站操作工证考试的复习重点是什么?
  • 如何取得专案/设计/设定/物件的属性
  • ETCD学习笔记
  • 手表--带屏幕音响-时间制切换12/24小时
  • 从零开始学习单片机18
  • 《云原生架构从崩溃失控到稳定自愈的实践方案》