android alarmmanager后台,Android各版本AlarmManager使用

一、长时间定时任务,比较Timer、Hnadler、AlarmManager

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

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

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

二、使用AlarmManager

通过上面的分析,我们可以明显感受到AlarmManager在长时间定时任务中的优点,下面来说说它的用法(由于AlarmManager在不同的Android版本都有修改,所以如果想使用AlarmManager需要处理不同版本问题)

1. 初始化PendingIntent

Intent intent = new Intent(ALARM_ACTION_CODE);

PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),

REQUEST_CODE, intent,

PendingIntent.FLAG_CANCEL_CURRENT);

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

getActivity()方法、getBroadcast()方法、getService()方法

ALARM_ACTION_CODE,Intent传递给广播接收者的action,自己设定。

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

FLAG_CANCEL_CURRENT,如果要创建的PendingIntent已经存在了,那么在创建新的PendingIntent之前,原先已经存在的PendingIntent中的intent将不能使用。

FLAG_NO_CREATE,如果要创建的PendingIntent尚未存在,则不创建新的PendingIntent,直接返回null。

FLAG_ONE_SHOT,相同的PendingIntent只能使用一次,且遇到相同的PendingIntent时不会去更新PendingIntent中封装的Intent的extra部分的内容。

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对象的话,比较的是两个对象的内存地址。

2. 初始化AlarmManager

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

3. 设置重复执行的定时任务

这个就要区分Android版本了

4.4之前,SDK API < 19

alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,

SystemClock.elapsedRealtime(), TIME_INTERVAL, pendingIntent);

alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,

System.currentTimeMillis(), TIME_INTERVAL, pendingIntent);

第一个参数表示闹钟类型:一般为 AlarmManager.ELAPSED_REALTIME_WAKEUP或者 AlarmManager.RTC_WAKEUP。它们之间的区别就是前者是从手机开机后的时间,包含了手机睡眠时间;而后者使用的就是手机系统设置中的时间。所以如果设置为AlarmManager.RTC_WAKEUP ,那么可以通过修改手机系统的时间来提前触发定时事件。另外,对于相似的 AlarmManager.ELAPSED_REALTIME 和 AlarmManager.RTC 来说,它们不会唤醒 CPU 。所以使用的频率较少;

第二个参数表示任务首次执行时间:与第一个参数密切相关。第一个参数若为 AlarmManager.ELAPSED_REALTIME_WAKEUP ,那么当前时间就为 SystemClock.elapsedRealtime() ;若为 AlarmManager.RTC_WAKEUP ,那么当前时间就为 System.currentTimeMillis() ;

第三个参数表示两次执行的间隔时间:这个参数没什么好讲的,一般为常量;

第四个参数表示对应的响应动作:一般都是去发送广播,然后在广播接收 onReceive(Context context, Intent intent) 中做相关操作。

4.4之后,6.0之前, SDK API >= 19, SDK API < 23

alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,

SystemClock.elapsedRealtime(), pendingIntent);

查阅 Android 官网中关于 Android 4.4 API 会看到如下几句话:

b39f9e79ac4f

图片.png

6.0之后的版本,SDK API >= 23

alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,

SystemClock.elapsedRealtime(), pendingIntent);

再次打开 Android 官网中关于 Android 6.0 变更 ,发现在 Android 6.0 中引入了低电耗模式和应用待机模式。然后接着往下看 对低电耗模式和应用待机模式进行针对性优化 ,发现会有下面一段话:

b39f9e79ac4f

图片.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值