定时任务Alarm的深入理解

时间:2022-06-10 08:03:09

前言

之前写过了一遍关于定时任务的文章,这次看了郭神的新书《第一行代码》第二版,写的非常的好,于是把其中一段关于Alarm的介绍整理分享给大家,觉得写的好同志们请去购买正版支持一下。

正文

Android 中的定时任务一般有两种实现方式,一种是Timer类,一种是使用Android的Alarm机制。这两种方式在多数情况下都能实现类似的效果,但是Timer有一个明显的短板,它并不适合用于那些需要长期在后台运行的定时任务。

为了能让电池更加耐用,各种手机都会有自己的休眠策略,Android手机就会在长时间不操作的情况下自动让CPU进入到休眠状态,这就有可能导致Timer的定时任务无法正常运行。而Alarm具有唤醒CPU的功能,它可以保证在大多数情况下需要执行的定时任务的时候CPU都能正常工作。注意唤醒CPU和唤醒屏幕完全不是一个概念。

先复习一下Alarm的基本用法:

AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SETVICE);
int anHour = 60 * 60 *1000;
long triggerAtTime = SystemClock.elapsedRealtime() + anHour;
Intent i = new Intent(this, LongRunningService.class);
PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);

set()方法详解:

1、整型参数,用于指定AlarmManager的工作类型。
AlarmManager.ELAPSED_REALTIME:定时任务的触发时间从系统开机开始算起,但不会唤醒cpu。
AlarmManager.ELAPSED_REALTIME_WAKEUP:定时任务的触发时间从系统开机算起,但会算起cpu。
AlarmManager.RTC:让定时任务的触发时间从1970年1月1日0点开始算起,但不会唤醒cpu。
AlarmManager.RTC_WAKEUP:让定时任务的触发时间从1970年1月1日0点算起,但会唤醒cpu。

SystemClock.elapsedRealtime():获取到系统开机至今所经历时间的毫秒数。
System.currentTimeMillis():获取到1970年1月1日0点至今所经历时间的毫秒数。

2、定时任务的触发时间,以毫秒为单位。

3、PendingIntent ,具体触发的任务事件。

注意

从Android 4.4系统开始,Alarm任务的触发时间将会变得不准确,有可能会延迟一段时间后任务才能得到执行。但这并不是bug,而是系统在耗电性方面进行的优化。系统会自动检测目前有杜少Alarm任务存在,然后将触发时间相近的几个任务放在一起执行,这就可以大幅度的减少cpu被唤醒的次数,从而有效延长电池的使用时间。