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

深入探讨 Android 中的 AlarmManager:定时任务调度及优化实践

引言

在 Android 开发中,AlarmManager 是一个非常重要的系统服务,用于设置定时任务或者周期性任务。无论是设置一个闹钟,还是定时进行数据同步,AlarmManager 都是不可或缺的工具之一。然而,随着 Android 系统的不断演进,设备管理策略、尤其是电池管理策略(如 Doze 模式)不断变化,AlarmManager 的使用也变得复杂起来。本文将深入探讨 AlarmManager 的使用、工作原理、以及它在现代 Android 设备上的局限性,同时提供实际的代码演示和优化建议,帮助开发者更好地理解和使用这一工具。

AlarmManager 的基本概念和工作原理

什么是 AlarmManager?
AlarmManager 是 Android 中的一种系统服务,允许应用程序在未来某个时间点触发任务。通过 AlarmManager,开发者可以实现各种定时任务,最典型的如:闹钟、定期同步数据、定时通知等。

AlarmManager 的工作机制
AlarmManager 的核心原理是:设置一个定时任务,在未来某一时刻唤醒应用程序或系统服务执行指定操作。你可以选择在指定时间唤醒设备并执行操作(例如发出广播、启动服务等)。

AlarmManager 的触发类型
AlarmManager 提供了多种触发方式,主要包括以下几种:

RTC:基于当前时间来触发任务。如果设备处于休眠状态,则任务可能会被延迟执行。
RTC_WAKEUP:与 RTC 类似,但会在触发时间点唤醒设备。
ELAPSED_REALTIME:基于设备自启动以来的时间来触发任务,不受设备休眠影响。
ELAPSED_REALTIME_WAKEUP:与 ELAPSED_REALTIME 类似,但会在触发时间点唤醒设备。

AlarmManager 的常用方法

set():设置一个单次任务,任务将在指定的时间点触发。
setRepeating():设置一个周期性任务,任务将在指定时间间隔内重复执行。
setInexactRepeating():设置一个周期性任务,但系统会对时间进行一定的延迟,以优化电池消耗。

AlarmManager 的使用场景

闹钟和提醒功能:常见于需要在指定时间点提醒用户的应用,例如闹钟应用、待办事项提醒等。
定期同步数据:一些应用需要定期从网络获取数据,AlarmManager 可以用于定期启动一个同步任务,保持数据的实时性。
定时发送通知:例如,定时推送新闻、天气预报等信息。
后台任务调度:即使应用被关闭,AlarmManager 仍然可以触发任务,适用于需要在指定时间触发后台任务的应用场景。
AlarmManager 的基础使用:实现一个简单的定时任务
创建一个简单的定时任务
下面是一个简单的例子,展示如何使用 AlarmManager 设置一个定时任务,在 10 秒后触发并显示一个 Toast。

步骤一:设置 AlarmManager

public class MainActivity extends AppCompatActivity {private AlarmManager alarmManager;private PendingIntent pendingIntent;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);// 创建一个广播接收器Intent intent = new Intent(this, AlarmReceiver.class);pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);// 设置定时任务 - 这里使用 RTC_WAKEUP,定时在 10 秒后触发long triggerAtMillis = System.currentTimeMillis() + 10000;  // 10秒后触发alarmManager.set(AlarmManager.RTC_WAKEUP, triggerAtMillis, pendingIntent);}
}

步骤二:创建接收广播的组件

public class AlarmReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, "定时任务已触发!", Toast.LENGTH_SHORT).show();}
}

说明:
MainActivity 中通过 AlarmManager 设置了一个定时任务,定时在 10 秒后触发。
触发时会通过 PendingIntent 启动一个广播接收器 AlarmReceiver,并在 onReceive() 方法中执行相应的操作(如显示 Toast)。
任务触发的时间是基于当前时间的 10 秒后。
流程图:
在这里插入图片描述

用户打开应用:用户启动应用并进入 MainActivity。
设置定时任务:应用通过 AlarmManager 设置定时任务,在 10 秒后触发。
定时任务触发:在 10 秒后,AlarmReceiver 的 onReceive() 被调用,显示 Toast 提示用户。
使用 AlarmManager 实现周期性任务
需求背景
除了设置一次性的定时任务外,很多应用还需要实现定期的任务调度。例如,某些应用需要定期同步数据或者发送提醒。

示例:定期同步数据

@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);// 创建一个广播接收器Intent intent = new Intent(this, AlarmReceiver.class);pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);// 设置周期性任务,每30秒触发一次long startTime = System.currentTimeMillis();long interval = 30000;  // 30秒alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, startTime, interval, pendingIntent);
}

说明:
setRepeating() 方法设置了一个定期任务,每隔 30 秒触发一次。
每次任务触发时,都会唤醒设备并执行 AlarmReceiver 中的代码。
注意事项:
在 Android 6.0 及以上版本中,setRepeating() 方法会受到 Doze 模式的影响。如果设备进入 Doze 模式,周期任务可能会被延迟。
为了适应更严格的电池优化,推荐使用 JobScheduler 或 WorkManager 来替代 AlarmManager。
AlarmManager 的局限性与优化实践

  1. Doze 模式的影响
    从 Android 6.0(API 23)开始,Android 引入了 Doze 模式来延长电池使用寿命。当设备处于空闲状态时,系统会限制后台任务的执行,AlarmManager 可能无法准时触发任务。这使得基于 AlarmManager 的周期性任务不再可靠,尤其是当设备长时间未充电且未被使用时。

解决方案:
使用 setExact() 和 setExactAndAllowWhileIdle():这些方法可以确保任务在指定的时间点精确执行,即使设备处于 Doze 模式。
使用 JobScheduler 或 WorkManager:这些 API 设计用来适应 Doze 模式,能够更加智能地安排任务的执行,确保任务在合适的时间执行。
2. 任务精确性与系统负载
AlarmManager 的任务并不保证在精确的时间点触发。尤其是在设备负载较高时,任务可能会被延迟执行。因此,如果你的应用对任务的精确性要求较高,使用 AlarmManager 可能不是最优的选择。

解决方案:
考虑使用 JobScheduler 或 WorkManager:这两个 API 能够更智能地管理任务的执行,能够根据系统资源和电池状态决定任务的调度时机。
3. 优化电池消耗
频繁地设置定时任务,尤其是周期性任务,可能会导致电池消耗过快。为此,可以通过以下方式来优化电池使用:

减少定时任务的频率:如果任务不需要精确执行,可以减少触发的频率,减少系统调度的负担。
使用 setInexactRepeating():该方法会让系统自行调整任务触发的时间,以提高电池效率。
高级用法:结合 JobScheduler 和 AlarmManager 使用
虽然 AlarmManager 是一个强大的工具,但在 Android 6.0 及以上版本,JobScheduler 和 WorkManager 更适合现代的电池管理策略。因此,在需要定期执行任务的场景中,建议使用 JobScheduler 或 WorkManager 来代替传统的 AlarmManager。

以下是一个结合 JobScheduler 使用的示例:

JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo jobInfo = new JobInfo.Builder(0, new ComponentName(this, MyJobService.class)).setPersisted(true).setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED).setPeriodic(30000) // 30秒间隔.build();
jobScheduler.schedule(jobInfo);

在这个示例中,我们使用 JobScheduler 来定期执行任务,并且可以设置更多的约束条件,如需要无流量网络、设备是否充电等。

总结
本文深入探讨了 Android 中的 AlarmManager,从基础的定时任务到周期性任务的实现,详细分析了其使用场景、工作原理以及一些实际应用中的优化技巧。在 Android 设备的电池管理策略不断变化的背景下,AlarmManager 的使用也需要结合 JobScheduler 或 WorkManager 进行优化,以确保任务能够高效、准确地执行。希望通过本文的分享,开发者能更好地理解并合理利用 AlarmManager,构建更为高效、可靠的 Android 应用。

相关文章:

深入探讨 Android 中的 AlarmManager:定时任务调度及优化实践

引言 在 Android 开发中,AlarmManager 是一个非常重要的系统服务,用于设置定时任务或者周期性任务。无论是设置一个闹钟,还是定时进行数据同步,AlarmManager 都是不可或缺的工具之一。然而,随着 Android 系统的不断演…...

西电-算法分析-研究生课程复习笔记

24年秋的应该是张老师最后一次用卷面考试,他说以后这节课的期末考试都是在OJ上刷题了张老师上课还挺有意思的,上完之后能学会独立地思考算法设计问题了。整节课都在强调规模压缩这个概念,考试也是考个人对这些的理解,还挺好玩的哈…...

编译时找不到需要的库,如何在PyCharm中为你的项目添加需要的库

丰富的库支持是 Python 语言的一大特点,但是在使用 PyCharm 进行Python 代码编译的时候,遇到一些需要使用到的库提示不能解析时,该如何添加呢? 比如下图所示的代码,可以看到需要使用 selenium、b4、jieba 这些库&…...

ip addr 命令给Linux网络接口配置多个IP地址值

问一下Chatgpt 怎么使用ip addr 命令给Linux网络接口配置多个IP地址值 根据Chatgpt的提示执行了命令,命令执行成功,看下执行结果。 ifconfig 命令查看接口IP地址 ip addr show 命令查看接口IP地址...

C#语言的数据库编程

C#语言的数据库编程 在现代软件开发中,数据库是不可或缺的一部分。无论是企业级应用还是个人项目,数据的存储与管理都是程序的核心功能之一。C#作为一种强类型、面向对象的编程语言,广泛应用于Windows平台的开发,尤其是在构建与数…...

时频分析之S变换

S变换的提出 1996年,由R.G Stockwell 提出了S变换,和其他时频分析工具一样,通过S变换,我们可以同时从时域以及频域观察一个信号的能量分布。S变换融合了短时傅里叶变换和小波变换的优点。关于S变换,最早发表于TSP上的…...

第二十八周学习周报

目录 摘要Abstract1 GFPGAN1.1 总体结构1.2 实验研究1.3 代码分析 总结 摘要 本周主要的学习内容是GFPGAN模型。GFPGAN是一种基于生成对抗网络(GAN)的模型,其利用封装在预训练的人脸GAN中的丰富多样的先验进行人脸图像的修复。这种生成面部先验(GFP&…...

SurfaceFlinger MessageQueue原理

SurfaceFlinger MessageQueue 有2个作用: 处理SurfaceFlinger INVALIDATE、REFRESH事件管理SurfaceFlinger主线程挂起和恢复 SurfaceFlinger::run() { while (true) { mEventQueue->waitMessage(); } } waitMessage {do {IPCThreadState::self()->flushComm…...

component-动态控制 div width 的值 根据传入的变量决定width的值 vue

1.实现 根据参数的值&#xff0c;div显示不同的长度 <div class"node-line" :style"lineProgress"></div> <script>export default {name: "trainSummaryInfo",data(){return{linePercentage:200,}},computed:{lineProgress…...

C#中的常用集合

目录 一、动态数组ArrayList 二、List 三、栈&#xff08;Stack&#xff09; 四、队列&#xff08;Queue&#xff09; 五、字典&#xff08;Dictionary&#xff09;,int> 一、动态数组ArrayList ArrayList 是 C# 中提供的一种动态数组类&#xff0c;位于命名空间 Syste…...

插入实体自增主键太长,mybatis-plaus自增主键

1、问题 spring-boot整合mybtais执行insert语句时&#xff0c;主键id为长文本数据。 2、分析问题 1)数据库主键是否自增 2&#xff09;数据库主键的种子值设置的多少 3、解决问题 1&#xff09;数据库主键设置的时自增 3&#xff09;种子值是1 所以排查是数据库的问题 4、继…...

晨辉面试抽签和评分管理系统之一:考生信息管理和编排

晨辉面试抽签和评分管理系统&#xff08;下载地址:www.chenhuisoft.cn&#xff09;是公务员招录面试、教师资格考试面试、企业招录面试等各类面试通用的考生编排、考生入场抽签、候考室倒计时管理、面试考官抽签、面试评分记录和成绩核算的面试全流程信息化管理软件。提供了考生…...

【MySQL】MVCC详解, 图文并茂简单易懂

欢迎来到啊妮莫的学习小屋 祝读本文的朋友都天天开心呀 目录 MVCC简介快照读与当前读快照读当前读 隔离级别隐藏字段和Undo Log版本链✨MVCC原理--ReadView✨ReadView简介设计思路适用隔离级别重要内容 ReadView规则MVCC整体流程 不同隔离级别下的MVCC读已提交可重复读 总结 M…...

中国数字化发展的问题与机会

橙蜂智能公司致力于提供先进的人工智能和物联网解决方案,帮助企业优化运营并实现技术潜能。公司主要服务包括AI数字人、AI翻译、埃域知识库、大模型服务等。其核心价值观为创新、客户至上、质量、合作和可持续发展。 橙蜂智农的智慧农业产品涵盖了多方面的功能,如智能化推荐、…...

【ROS2】☆ launch之Python

☆重点 ROS1和ROS2其中一个很大区别之一就是launch的编写方式。在ROS1中采用xml格式编写launch&#xff0c;而ROS2保留了XML 格式launch&#xff0c;还另外引入了Python和YAML 编写方式。选择哪种编写取决于每位开发人员的爱好&#xff0c;但是ROS2官方推荐使用Python方式编写…...

如何稳定使用 O1 / O1 Pro,让“降智”现象不再困扰?

近期&#xff0c;不少朋友在使用 O1 或 O1 Pro 模型时&#xff0c;都会碰到“降智”或“忽高忽低”的智力波动&#xff0c;比如无法识图、无法生成图片、甚至回答准确度也不稳定。面对这些问题&#xff0c;你是不是也感到头疼呢&#xff1f; 为了找到更可靠的解决办法&#xf…...

zookeeper监听机制(Watcher机制)

文章目录 引言I zookeeper监听机制Watcher机制实现分布式的通知功能触发事件种类Watcher的三个过程II watch机制特点一次性触发事件封装event异步发送先注册再触发常见的通知状态和事件类型III 应用案例(Kafka)Kafka的消息模型Kafka在Zookeeper中保存的元数据Kafka 基于Contr…...

docker 启动 nacos 单机模式

docker 启动 nacos 单机模式 # 拉取镜像# 启动&#xff0c;如果不拉镜像会自动拉取最新的 image docker run --name standalong_nacos -p 8848:8848 -p 9848:9848 -p 9849:9849 -e MODEstandalone -d nacos/nacos-server# 状态查看外部访问验证 输入部署的 docker ip 地址以及…...

学习threejs,导入babylon格式的模型

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.BabylonLoader babyl…...

03.MPLS静态LSP配置实验

MPLS静态LSP配置实验 1、实验环境2、基础配置开启全局mpls接口下开启mpls配置静态LSP配置FEC从1.1.1.1到3.3.3.3配置FEC从3.3.3.3到1.1.1.13、信息查看查看LFIB表(标签转发信息表)查看FIB表(转发信息表)查看详细FFIB表tracert lsp iptracert -vping lsp ip4、抓包验证1、实…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...

Mysql故障排插与环境优化

前置知识点 最上层是一些客户端和连接服务&#xff0c;包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念&#xff0c;为通过安全认证接入的客户端提供线程。同样在该层上可…...