Android 闹钟服务AlarmManager

一、通常我们实现定时任务有三种方式:

        Timer,有一个明显的问题,它并不太适合用于需要长期在后台运行的定时任务。我们都知道,为了能让电池更加耐用,每种手机都会有自己的休眠策略,Android手机就会在长时间不操作的情况下自动让CPU进入睡眠状态,这就有可能导致Timer中的定时任务无法正常运行。

        Hnadler,Handler的postDelay方法也可以实现定时操作,它同样也是不靠谱的,因为默认Hnadler依赖于线程(main线程或者子线程),所以只要进程被杀死,所有相关的线程都被晒死,所以handler中的定时操作就无效了。Timer也一样,因为Timer实际上是另起一个子线程,进程被杀,子线程当然也被杀了。

        AlarmManager,它通过pendingIntent具有唤醒未启动进程的功能,即可以保证每次需要执行定时任务的时候CPU都能正常工作。但是当设备关机和重启后,闹钟将被清除。

二、PendingIntent

        PendingInent,Intent 更加倾向于去立即执行某个动作,而 PendingIntent 更加倾向于在某个合适的时机去执行某个动作。所以,也可以把 PendingIntent 简单地理解为延迟执行的 Intent。
getActivity()方法、getBroadcast()方法、getService()方法

        PendingIntent.FLAG_CANCEL_CURRENT,pendingIntent的第四个参数如果直接传0,表示你不打算通过任何一个flag来控制pendingIntent的创建。下面说说pendingIntent提供的四种flag:

  1. FLAG_CANCEL_CURRENT,如果要创建的PendingIntent已经存在了,那么在创建新的PendingIntent之前,原先已经存在的PendingIntent中的intent将不能使用。
  2. FLAG_NO_CREATE,如果要创建的PendingIntent尚未存在,则不创建新的PendingIntent,直接返回null。
  3. FLAG_ONE_SHOT,相同的PendingIntent只能使用一次,且遇到相同的PendingIntent时不会去更新PendingIntent中封装的Intent的extra部分的内容。
  4. FLAG_UPDATE_CURRENT,如果要创建的PendingIntent已经存在了,那么在保留原先PendingIntent的同时,将原先PendingIntent封装的Intent中的extra部分替换为现在新创建的PendingIntent的intent中extra的内容。

       比较pendingIntent是否相同:
        PendingIntent重写了equals方法,判定两个PendingIntent是否相同的依据是它封装的Intent是否“相同”和requestCode是否一致。

        注意,“相同”上打了引号,这是因为在比较PendingIntent中封装的intent时是否相同时,使用的是Intent的filterEquals方法,该方法认为只要两个intent具有相同的action、data、categories、components、type和flags(这个flags是intent的flags)就认为它们两个是“相同”的,filterEquals是不会比较两个intent的extra部分和内存地址的。

        另外需要注意的是,Intent并没有重写equals方法,所以如果使用Intent的equals方法比较两个intent对象的话,比较的是两个对象的内存地址。

三、闹钟类型

        1、AlarmManager.ELAPSED_REALTIME

        闹钟在手机睡眠状态下不可用,该状态下闹钟使用相对时间(相对于系统启动开始),状态值为3,SystemClock.elapsedRealtime() 获取(从开机到现在的毫秒数,包括手机的睡眠时间),设备休眠时并不会唤醒设备。 

        2、AlarmManager.ELAPSED_REALTIME_WAKEUP 

        闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟也使用相对时间,状态值为2,与ELAPSED_REALTIME基本功能一样,只是会在设备休眠时唤醒设备。 

        3、AlarmManager.RTC 

        闹钟在睡眠状态下不可用,该状态下闹钟使用绝对时间,即当前系统时间,状态值为1,可以通过 System.currentTimeMillis()获取,设备休眠时并不会唤醒设备。  

        4、AlarmManager.RTC_WAKEUP 

        表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟使用绝对时间,状态值为0,与RTC基本功能一样,只是会在设备休眠时唤醒设备。

        5、AlarmManager.POWER_OFF_WAKEUP 

        表示闹钟在手机关机状态下也能正常进行提示功能,所以是5个状态中用的最多的状态之一,该状态下闹钟也是用绝对时间,状态值为4;不过本状态好像受SDK版本影响,某些版本并不支持;

四、设置定时任务

        从API19(android4.4)开始, 为了节能省电(减少系统唤醒和电池使用)。使用Alarm.set()和Alarm.setRepeating()已经不保证精确性,既不会按照我们设置的预期时间执行,因此我们需要根据不同版本执行不同操作,

        4.4以前(<19):我们可以使用set或者setRepeating方法

        4.4以后6.0以前(>23version>=19):setExpact方法可以精确执行定时任务

        6.0版本以后(>=23):需要使用setExactAndAllowWhildIdle方法,因为Android 6.0 中引入了低电耗模式和应用待机模式,低电耗模式下需要使用该方法,也可以使用setAlarmClock方法,但该方法有个局限性就是在闹钟触发前会退出低电耗模式。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值