简介
Android AlarmManagerService是Android系统中的一个系统服务,用于实现定时任务的调度和触发。通过AlarmManagerService,应用程序可以在指定的时间点或者周期性地执行某个任务。
AlarmManagerService的主要功能包括:
1. 计算和触发定时任务:AlarmManagerService会根据应用程序注册的定时任务信息,计算下一次任务的触发时间,并在指定的时间点触发任务。
2. 管理和处理定时任务:AlarmManagerService负责管理和处理所有的定时任务。它会根据任务的触发时间和设备的休眠状态,决定是否唤醒设备来触发任务。
3. 支持不同类型的定时任务:AlarmManagerService支持多种不同类型的定时任务,包括一次性任务、重复任务、间隔任务等。应用程序可以根据自己的需求选择相应的任务类型。
4. 与其他系统服务的集成:AlarmManagerService与其他系统服务紧密集成,在任务触发时可以与其他系统服务进行交互。例如,可以通过AlarmManagerService来触发一个定时通知,或者启动一个后台服务。
Alarm的触发过程
下图1是alarm触发的一个大致流程。
首先应用会调用AlarmManager提供的set接口,将一个含有触发时间和触发事件的alarm对象添加到一个由AlarmManager服务维护的alarm列表中,同时alarm列表会计算出最优先的alarm对象(最先起来)设置到底层RTC设备中。但这个时间点到了,RTC会上发信息并通知AlarmManager服务去触发相应的事件。
Alarm管理机制的变化
Android4.4以及后面的版本对Alarm的管理发生了比较大的变化,首先来看下AlarmManager的构造方法。
AlarmManager(IAlarmManager service, Context ctx) {
mService = service;
final int sdkVersion = ctx.getApplicationInfo().targetSdkVersion;
mAlwaysExact = (sdkVersion < Build.VERSION_CODES.KITKAT);
}
private long legacyExactLength() {
return (mAlwaysExact ? WINDOW_EXACT : WINDOW_HEURISTIC);
}
从Android 4.4版本开始引入了Exact闹钟的概念,既然有Exact(精确),那自然有非精确,但为了兼容旧版本,可以看到legacyExactLength方法中,如果sdkVersion是API19(Android4.4)之前的,所有的闹钟都是精确的闹钟,否则是Heuristic的。
接下来看看set方法的注释:
* Beginning in API 19, the trigger time passed to this method
* is treated as inexact: the alarm will not be delivered before this time, but
* may be deferred and delivered some time later. The OS will use
* this policy in order to "batch" alarms together across the entire system,
* minimizing the number of times the device needs to "wake up" and minimizing
* battery use. In general, alarms scheduled in the near future will not
* be deferred as long as alarms scheduled far in the future.
* With the new batching policy, delivery ordering guarantees are not as
* strong as they were previously. If the application sets multiple alarms,
* it is possible that these alarms' actual delivery ordering may not match
* the order of their requested delivery times. If your application has
* strong ordering requirements there are other APIs that you can use to get
* the necessary behavior; see {@link #setWindow(int, long, long, PendingIntent)}
* and {@link #setExact(int, long, PendingIntent)}.
* Applications whose {@code targetSdkVersion} is before API 19 will
* continue to get the previous alarm behavior: all of their scheduled alarms
* will be treated as exact.
翻译:从API19开始,通过这个方法设置的alarm都被认为是非精确的,这个alarm不会再设置的时间点之前触发,但可能会再设置的时间点后适当延迟触发。Android系统会根据一套规则,将一组触发时间类似的alarm以batch的形式保存下来,一旦batch的时间到了,便会将这个batch中的alarm一起触发,这样做的目的是将系统唤醒(如果是wake up类型的闹钟,首先需要唤醒系统)的次数降到最低,以达到省电的目的。
Batch的结构如图2: