Android WorkManager入门(一)

news2024/12/26 9:24:02

WorkManager入门

  • 前言
  • 一、WorkManager是什么?
  • 二、使用
    • 1.添加依赖
    • 2.定义工作
    • 3.创建 WorkRequest并提交 一次性的任务(OneTimeWorkRequest)
    • 4.setExpedited 加急方法
    • 5. setInitialDelay 延时任务
    • 6.约束
  • 总结
  • 参考资料


前言

在当今快节奏的生活中,移动设备已经成为我们日常工作和生活不可或缺的一部分。然而,随着应用程序的复杂性不断增加,开发人员面临着一个重要的挑战:如何在后台执行任务,而不会影响用户的体验和设备的性能?
在过去,开发人员通常使用传统的后台服务或定时任务来解决这个问题。然而,这些方法往往很复杂,需要大量的代码和资源,并且很难管理和调度任务。幸运的是,谷歌最近推出了一个新的解决方案:安卓WorkManager。
安卓WorkManager是一个灵活、强大的后台任务调度库,旨在帮助开发人员轻松管理和执行后台任务。它提供了一种简单的方式来调度任务,无论是一次性任务、定期任务还是延迟任务,都可以很容易地实现。同时,WorkManager还提供了一系列强大的功能,如任务链、约束条件和灵活的重试机制,以确保任务能够在最佳的时间和条件下执行。
在本文中,我们将深入探讨安卓WorkManager的原理和用法,并通过实际示例演示如何使用它来解决常见的后台任务问题。无论您是一名初学者还是一名有经验的开发人员,本文都将为您提供宝贵的知识和实用的技巧,帮助您更好地利用安卓WorkManager来优化您的应用程序。让我们一起开始这段关于安卓WorkManager的探索之旅吧!

好吧,不多BB,其实是因为安卓12以上想起后台服务必须要悬浮窗权限,想起还有个WorkManager这种东西,去官网学习然后总结一下。


一、WorkManager是什么?

我们先copy一下官方的解释 ,借鉴,借鉴,读书人的事怎么能叫抄
对于WorkManager,官方是这样描述的:
WorkManager 是适合用于持久性工作的推荐解决方案。如果工作始终要通过应用重启和系统重新启动来调度,便是持久性的工作。由于大多数后台处理操作都是通过持久性工作完成的,因此 WorkManager 是适用于后台处理操作的主要推荐 API。

用人话来简单描述解释一下就是说:应用后台操作,现在安卓官方推荐使用WorkManager了,官方还给了一张WorkManager与延时后台任务的关系图便于我们理解

在这里插入图片描述

我翻译了一下有些不太准,凑合着看吧

类型周期使用方式
立即(马上执行)一次性OneTimeWorkRequest 和 Worker。如需处理加急工作,请对 OneTimeWorkRequest 调用 setExpedited()。
可延期(延期执行)一次性或定期PeriodicWorkRequest 和 Worker。
长期运行(满足条件执行)一次性或定期任意 WorkRequest 或 Worker。在工作器中调用 setForeground() 来处理通知。

二、使用

1.添加依赖

写下这篇文章时的最新依赖是 2023 年 2 月 8 日的 2.8.0 版本

将以下依赖项添加到应用的 build.gradle 文件中:

dependencies {
    def work_version = "2.8.0"

    // (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"
}

具体来说,上述配置包括以下依赖项:

  1. androidx.work:work-runtime:用于Java项目的基本依赖项。
  2. androidx.work:work-runtime-ktx:用于Kotlin项目的基本依赖项,结合协程使用。
  3. androidx.work:work-rxjava2:可选的依赖项,用于支持使用RxJava2编写任务。
  4. androidx.work:work-gcm:可选的依赖项,用于支持使用GCMNetworkManager调度任务(API级别低于23的设备)。
  5. androidx.work:work-testing:可选的依赖项,用于编写测试辅助工具。
  6. androidx.work:work-multiprocess:可选的依赖项,用于支持任务在多进程中运行。

2.定义工作

在具体使用时,我们需要先定义工作,我们先创建一个MyWorker类,继承woker,注意不要导错包。

写好后应该是这个样子的

import android.content.Context
import android.util.Log
import androidx.work.Worker
import androidx.work.WorkerParameters

class MyWorker(appContext: Context, workerParams: WorkerParameters):Worker(appContext, workerParams) {
    companion object{
        private const val TAG = "MyWorker"
    }


    override fun doWork(): Result {

        Log.d(TAG, "doWork: 我正在做一些工作")

        return Result.success()
    }

}

在doWork()这个方法中,我们可以进行一系列操作,像是下载图片啊,更新安装包啊,都是可以的,方法需要一个Result 回参,我们看看Result 这个类


我们再借鉴一下官方的说法:
从 doWork() 返回的 Result 会通知 WorkManager 服务工作是否成功,以及工作失败时是否应重试工作。

  • Result.success():工作成功完成。
  • Result.failure():工作失败。
  • Result.retry():工作失败,应根据其重试政策在其他时间尝试。

所以示例中的return Result.success()就表示工作执行成功了

3.创建 WorkRequest并提交 一次性的任务(OneTimeWorkRequest)

示例嘛,我们就在activity中调用WorkRequest了,在activity的onCreate()方法中调用如下代码:

import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkRequest

 //通过OneTimeWorkRequestBuilder创建WorkRequest
        val mWorkerRequest : WorkRequest = OneTimeWorkRequestBuilder<MyWorker>()
        //                .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
            .build()

        //通过WorkManager提交WorkRequest,执行MyWorker
        WorkManager
            .getInstance(this)
            .enqueue(mWorkerRequest)

运行后可以在logcat中看到如下日志:
在这里插入图片描述

2023-12-19 11:13:46.675 31499-31570 MyWorker                com.example.test                     D  doWork: 我正在做一些工作
2023-12-19 11:13:46.684 31499-31541 WM-WorkerWrapper        com.example.test                     I  Worker result SUCCESS for Work [ id=9012bb3b-ccbb-4bbe-8e1c-1c84264410fb, tags={ com

对于这种简单的只需要执行一次的任务,推荐我们使用静态的方式创建

        //通过静态方式创建的
        val mWorkerRequest1 = OneTimeWorkRequest.from(MyWorker::class.java)

        //通过WorkManager提交WorkRequest,执行MyWorker
        WorkManager
            .getInstance(this)
            .enqueue(mWorkerRequest1)

同样会输出以下日志

2023-12-19 11:18:16.519 32612-32682 MyWorker                com.example.test                     D  doWork: 我正在做一些工作
2023-12-19 11:18:16.533 32612-32663 WM-WorkerWrapper        com.example.test                     I  Worker result SUCCESS for Work [ id=5cfd14e8-791f-4b31-968c-c5404963ebba, tags={ com.example.test.MyWorker } ]

缺点呢就是不能进行其他灵活的配置,比如加急,延时和添加约束。

下面介绍的setXXX方法都是WorkRequest的衍生方法,使用需要在.build()方法前

4.setExpedited 加急方法

如果有多个任务,我们还可以使用setExpedited方法对任务进行加急,我们来看看源码
先看看setExpedited方法:

这个方法表示为任务请求加急的意思,需要一个OutOfQuotaPolicy入参,我们来看看OutOfQuotaPolicy类

从上面的源码来看我们只有一个任务时,设置.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)与不设置是等价的。而设置了加急的任务我们怎么知道是被加急了呢?在某些安卓设备上我们能收到通知,这与设备厂商和安卓版本有关。如果能收到的话我们创建Worker时使用CoroutineWorker,并集成其getForegroundInfo方法,然后,在 doWork() 内将其传递给 setForeground()。这样做会在 Android 12 之前的版本中创建通知。

您应该将 setForeground() 封装在 try/catch 块中,以捕获可能出现的 IllegalStateException。如果您的应用此时无法在前台运行,便可能会发生这类异常。在 Android 12 及更高版本中,您可以使用更详细的 ForegroundServiceStartNotAllowedException。

5. setInitialDelay 延时任务


下面这段代码表示会延迟十分钟再执行。

        val mWorkerRequest2 = OneTimeWorkRequestBuilder<MyWorker>()
            .setInitialDelay(10, TimeUnit.MINUTES)
            .build()

        //通过WorkManager提交WorkRequest,执行MyWorker
        WorkManager
            .getInstance(this)
            .enqueue(mWorkerRequest2)

执行工作器的确切时间还取决于 WorkRequest 中使用的约束和系统优化方式。WorkManager 经过设计,能够在满足这些约束的情况下提供可能的最佳行为。

6.约束

上面的注意事项提到了约束,及一些特定的条件,android也帮我们归纳好了:

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

那么这些约束要怎么使用呢?

比如我们要在充电时做一些工作,就可以这样写

        val constraints = Constraints.Builder()
            .setRequiresCharging(true)
            .build()

        val mWorkerRequest3 = OneTimeWorkRequestBuilder<MyWorker>()
            .setConstraints(constraints)
            .build()

        //通过WorkManager提交WorkRequest,执行MyWorker
        WorkManager
            .getInstance(this)
            .enqueue(mWorkerRequest3)

因为我是USB充电调试,日志输出为

2023-12-19 13:22:14.597 27819-27906 MyWorker                com.example.test                     D  doWork: 我正在做一些工作
2023-12-19 13:22:14.616 27819-27870 WM-WorkerWrapper        com.example.test                     I  Worker result SUCCESS for Work [ id=c3898a3d-13d1-4dc5-86e4-234f282dfcec, tags={ com.example.test.MyWorker } ]

总结

本文主要介绍了WorkManager的一些基础使用,未完期待…

参考资料

WorkManager API
使用 WorkManager 调度任务
官方GitHub 代码示例
WorkManager 使用入门

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

协同物联:设备物联与车间数据采集的融合

随着工业4.0和智能制造的快速发展&#xff0c;物联网技术在工业领域的应用逐渐普及。其中&#xff0c;协同物联、设备物联和车间数据采集技术对于提升企业生产效率和降低运营成本具有重要意义。本文将深入探讨这些技术在现代工业环境中的应用及它们如何共同推动企业向数字化转型…

【Linux基础】3. 文件基本属性

文章目录 【 1. 文件的属主和属组 】【 2. 显示文件的类型、权限 】2.1 文件类型2.2 文件权限 【 3. 更改文件属性 】3.1 chgrp 更改文件属组3.2 chown 更改文件所有者3.3 更改文件权限3.3.1 数字法更改文件权限3.3.2 符号法更改文件权限 【 1. 文件的属主和属组 】 Linux 系统…

山海鲸开发者带你看:智慧医疗解决方案

在之前的文章中我为大家介绍了山海鲸可视化软件的一些基础操作以及一些解决方案&#xff0c;让大家知道了山海鲸可视化软件是一款可以免费自由开发的数字孪生软件。在本文&#xff0c;我将带大家了解山海鲸可视化的智慧医疗解决方案&#xff0c;让大家知道山海鲸可视化能在医疗…

maui中实现加载更多 RefreshView跟ListView(2)

一个类似商品例表的下拉效果&#xff1a; 代码 新增个类为商品商体类 public class ProductItem{public string ImageSource { get; set; }public string ProductName { get; set; }public string Price { get; set; }}界面代码&#xff1a; <?xml version"1.0&quo…

现代化智慧档案馆八防十防建设调研样本

以下是一份完整的解决方案&#xff0c;包括方案介绍、方案优势、实施方案、预算和清单、实施时间和进度计划以及可能遇到的难点和解决方案。 方案介绍 档案库房八防十防环境一体化监控系统旨在为档案库房提供全方位的环境监控和管理&#xff0c;保障档案的安全、稳定和可靠。该…

C++前后函数的相互调用,函数的预定义,靠前的函数调用靠后的函数

好多时候我们习惯性的认为在C中函数的定义是没有顺序的关系的&#xff0c;如下所示 代码片段1 void func1() {cout << "func1" << "\n"; } void func2() {cout << "func2" << "\n"; }代码片段2 void fun…

浅析PAM市场价值

随着全球数字化蓬勃发展&#xff0c;云计算、人工智能、大数据、5G等技术的应用范围不断扩大&#xff0c;在企业运用新技术提高自身效率的同时也面临着更多由新技术诱发的网络威胁&#xff0c;全球网络威胁形势愈发严峻。网络攻击行为日趋复杂&#xff0c;构建全面的安全防护体…

端口占用命令 netstat (centos)+netstat (windows)

linux 1.使用 netstat 命令查看端口占用情况 netstat -tlnp 使用 -p 选项查看进程信息。 使用 -t 选项列出 TCP 协议的连接&#xff1a;类似&#xff08;使用 -u 选项列出 UDP 协议的连接&#xff1a;&#xff09; 2.查找占用指定端口号的应用信息 netstat -tlnp | grep 3…

基于SSM的高校疫情防控出入信息管理系统的设计与实现论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本高校疫情防控出入信息管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞…

【PHP入门】1.3-数据类型、转换、判断

-数据类型- 数据类型&#xff1a;data type&#xff0c;在 PHP中指的是存储的数据本身的类型&#xff0c;而不是变量的类型。 PHP是一种弱类型语言&#xff0c;变量本身没有数据类型。 1.3.1PHP的八种数据类型 在PHP中将数据分为三大类八小类&#xff1a; 简单&#xff0…

【C语言】还不会【二维数组】!进来手把手教你,保姆级!!!

讲二维数组前&#xff0c;先讲一下sizeof()函数的用法&#xff1b; 目录 sizeof()函数 二维数组概念 二维数组创建 二维数组初始化 1&#xff0c;不完全初始化 2&#xff0c;完全初始化 二维数组下标 二维数组的输入和输出 二维数组的储存 变长数组 总结 sizeof()函数…

【QT】解决QTableView修改合并单元格内容无法修改到合并范围内的单元格

问题&#xff1a;修改合并单元格的内容 修改合并单元格的内容时&#xff0c;希望直接修改到合并范围内的单元格&#xff0c;Qt没有实现这个功能&#xff0c;需要自己写出 Delegate来实现 方案&#xff1a;Delegate class EditDelegate : public QStyledItemDelegate { public:…

使用vite搭建项目时,在启动vite后,浏览器显示页面:找不到localhost的网页

现象 在使用前端工具vite&#xff08;版本5&#xff09;&#xff0c;搭建vue3项目时&#xff0c;启动vite&#xff0c;浏览器显示页面&#xff1a;找不到localhost的网页, 起初怀疑是 未加参数 --host0.0.0.0,导致&#xff0c;后加上该参数后问题依旧 解决 将index.html页面…

如何进一步优化Ubuntu服务器的性能

导读&#xff1a; 要进一步优化Ubuntu服务器的性能&#xff0c;您可以考虑以下几个方面&#xff1a;优化软件包管理&#xff1a; Ubuntu使用APT&#xff08;Advanced Package Tool&#xff09;作为其软件包管理工具。为了提高性能&#xff0c;您可以采取以下措施 要进一步优化U…

Java接收并解析HL7协议数据

一、前言 HL7协议相信医疗行业的IT人员都不陌生&#xff0c;笔者由于接触时间比较短&#xff0c;乍一听“协议”还是比较懵&#xff0c;不自觉就把它和“HTTP”、"SOAP”之类的网络协议挂上关联&#xff0c;可事实上这个HL7只是一种数据格式&#xff0c;传输方式也可以使用…

Java操作windows系统功能(一)

Java可以通过调用Windows系统提供的命令行函数或调用外部程序来操作Windows系统。以下是一些常见的Java操作Windows的方法&#xff1a; 执行Windows命令&#xff1a;可以使用Java的Runtime类的exec()方法来执行Windows系统的命令。例如&#xff0c;可以使用以下代码来执行dir命…

堆---leetcode算法题目

文章目录 1. 数组中第K大元素-力扣 215 题 堆最重要的三个方法&#xff1a; heapify&#xff1a;建堆&#xff1a;找到第一个非叶子节点&#xff0c;比较这个节点和它的左右孩子&#xff0c;调整&#xff0c;如果交换了父节点和它的孩子的话&#xff0c;还需要再将交换后的孩子…

分享64个JavaGame源码总有一个是你想要的

分享64个JavaGame源码总有一个是你想要的 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 游戏项目名称 链接&#xff1a;https://pan.baidu.com/s/1Q4VlNlOMJU2yzoNagAcaCA?pwd6666 提取码&#xff1a;6666 Java Netty MMO 回…

SpringMVC-02

SpringMVC-02 SSM 框架集成与测试环境配置添加源代码 SSM 框架集成与测试 环境配置 IDEA 下创建项⽬ 创建Maven对应的Web项⽬ 配置 pom.xml 2.1. 修改 JDK 版本 <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><mav…

网络编程day3作业

多进程实现TCP并发服务器 #include<myhead.h>#define PORT 8888 #define IP "192.168.125.130"void hadder(int signo) {if(signo SIGCHLD){while(waitpid(-1,NULL,WNOHANG) > 0);} }int information_exchange(int newfd,struct sockaddr_in cin) {char b…