Android Alarm详解

1.     AndroidAlarm

1.1   简介

Alarm是android提供的定时器类,和Timer不同,使用Alarm可以在应用的生命周期之外定时触发特定操作。

1.2   构成要素

一个Alarm由以下4个要素构成:

(1)time type

Alarm有两种最基本类型,“elapsed real time”和“real time clock”,前者使用系统启动时的时间作为时间起点,后者使用UTC时间(1970 1 1 0)作为时间起点。所以“elapsedreal time”适用于间隔多长时间去触发一次操作,“real time clock”适用于在指定日期、时间(对时区敏感)去触发操作。

两种基本类型都扩展出了wakeup类型,wakeup类型的alarm触发时如果屏幕处在熄灭状态,cpu将会被唤醒。如果不使用wakeup类型,alarm将会在下次设备被唤醒时触发。

上述四种alarm类型标识如下:

ELAPSED_REALTIMEELAPSED_REALTIME_WAKEUPRTCRTC_WAKEUP

(2)trigger time

    触发时间,是从时间起点开始计算的毫秒数。

(3)interval (仅repeatingalarm需要)

    间隔时间,单位为毫秒

(4)pendingintent

        Pending intent 不仅用于指明Alarm触发后将要执行的操作,且用于唯一标识一个alarm,相同pending intent的alarm,新的将会覆盖旧的。

 

1.3   API

1.3.1       non-repeatingalarm

AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() +
        60 * 1000, alarmIntent);

例1-3-1

AlarmManager的set方法用于设置一次性定时器,三个参数分别为time type、trigger time、pending intent。例1设置了一个1分钟后触发的定时器。

1.3.2       repeatingalarm

AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

// Set the alarm to start at 8:30 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);

// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        1000 * 60 * 20, alarmIntent);

例1-3-2

AlarmManager的setRepeating方法用于设置经过间隔时间重复触发的定时器,相对于set方法,多了第三个参数interval(间隔时间)。

1.3.3       准确性

要注意的是,在Android4.4(API Level 19)以后,setRepeating方法设置的定时器触发时间并不是准确的,以下是官方文档中的说明:

 

原文地址:http://developer.android.com/training/scheduling/alarms.html

根据文档中的说明,setRepeating和setInexactRepeating之所以不准确,是系统会对他们进行统一调度,触发时间差不多的定时器会在同一时刻一次触发,以节省电量。

如果要使用能准确触发的定时器,我们要调用setExact()方法,该方法功能和set()方法一样,但在底层不允许系统去调整它的触发时间。

AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmMgr.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() +
        60 * 1000, alarmIntent);

例1-3-3

可惜的是,没有setExactRepeating()方法,也就是说准确且能重复的定时器只能由我们自己实现。实现的思路是:每次在定时器触发后设置一个新的定时器,触发时间增加一天。

 

1.3.4       误区

在测试setRepeating方法时,发现了一个误区,假定我设置定时器每日上午9点触发,那么定时器设置完后当日上午9点会准时触发,然后我会将日期往后调几日,测试其他日期上午9点是否会触发,每次调整时间后,定时器都会立即触发,而不是到9点。这是因为trigger time是一个毫秒数,而不是一个datetime值,当我们调整日期超过1天后,current timemillis一定大于trigger time,所以定时器会立即触发。

 

1.4   取消alarm

调用AlarmManager的cancel方法可以取消一个alarm,cancel方法需要传入pandingintent作为参数,代码如下:

// If the alarm has been set, cancel it.
if (alarmMgr!= null) {
    alarmMgr.cancel(alarmIntent);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值