Android之AlarmManager

本文只是记录一些零碎的东西

最近项目里需要做消息的推送,大概看了一下,在手机平台上,常用的方法有2种。一种是定时去服务器上查询数据,也叫

Polling,还有一种手机跟服务器之间维护一个 TCP 长连接,当服务器有数据时,实时推送到客户端,也就是我们说的 Push。

网上现在很多免费的推送SDK,比如,极光推送,使用也很简单,官网上文档很详细,究其实现原理,原来是基于Android提供的AlarmManager,定时运行任务,Google的API 在:https://developer.android.com/reference/android/app/AlarmManager.html,极光推送经过很多次迭代,其算法优化的特别好,将手机的能耗降到很低,这点值得称赞。

AlarmManager 是 Android 系统封装的用于管理 RTC 的模块,RTC (Real Time Clock) 是一个独立的硬件时钟,可以在 CPU 休

眠时正常运行,在预设的时间到达时,通过中断唤醒 CPU。这意味着,如果我们用 AlarmManager 来定时执行任务,CPU 可以正常

的休眠,只有在需要运行任务时醒来一段很短的时间。

AlarmManager这个类提供对系统闹钟服务的访问接口。Google文档里说的很清楚

从API 19开始,AlarmManager的机制都是非准确传递,操作系统将会转换闹钟,来最小化唤醒和电池使用。

去除了重复处理的函数

setRepeating(int type,long startTime,long intervalTime,PendingIntent pi)
该方法用于设置重复闹钟,第一个参数表示闹钟类型,第二个参数表示闹钟首次执行时间,第三个参数表示闹钟两次执行的

间隔时间,第三个参数表示闹钟响应动作。

建议采用如下方法: void setWindow (int type, long windowStartMillis, long windowLengthMillis, PendingIntent operation)


没有了repeat,就是设置了闹钟只能响一次了,应该是比较省电的。因为setWindow这个方法允许应用程序利用电池优化。

重复设置的问题好解决,我们的任务开始后重新设置一下Alarm就可以了。

官方还有一句话:but will be cleared if it is turned off and rebooted。重启好解决,监听开机广播就可以了,应用程序被kill,能想到

的只是通过服务自启动来实现,要不就把应用持久化到内存中(不建议)


int type : 闹钟类型

ELAPSED_REALTIME:闹钟在睡眠状态下不可用,使用的是相对系统启动时间

ELAPSED_REALTIME_WAKEUP:闹钟在睡眠状态下可用,使用的是相对系统启动时间

RTC:闹钟在睡眠状态下不可用,使用的是真实时间

RTC_WAKEUP:闹钟在睡眠状态下可用,使用的是真实时间

long windowStartMillis:闹钟开始时间
long windowLengthMillis:闹钟间隔

PendingIntent operation :闹钟的动作,在这里实现我们想实现的任务,google也给我们提供好了

Activity :PendingIntent.getActivity(Context context, int requestCode, Intent intent, int flags)

Broadcast:PendingIntent.getBroadcast(Context context, int requestCode, Intent intent, int flags)

Service:PendingIntent.getService(Context context, int requestCode, Intent intent, int flags)


pendingIntent的第4个参数

FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个相同的PendingIntent对象,那么就将先将已有的PendingIntent取消,然后重新生成一个PendingIntent对象。

FLAG_NO_CREATE:如果当前系统中不存在相同的PendingIntent对象,系统将不会创建该PendingIntent对象而是直接返回null。

FLAG_ONE_SHOT:该PendingIntent只作用一次。在该PendingIntent对象通过send()方法触发过后,PendingIntent将自动调用cancel()进行销毁,那么如果你再调用send()方法的话,系统将会返回一个SendIntentException。

FLAG_UPDATE_CURRENT:如果系统中有一个和你描述的PendingIntent对等的PendingInent,那么系统将使用该PendingIntent对象,但是会使用新的Intent来更新之前PendingIntent中的Intent对象数据,例如更新Intent中的Extras。


一个简单的以广播形式调用的封装

<span style="font-size:14px;">/**
 *  以服务形式 开启 Alarm
 * @param context   The Context in which this PendingIntent should perform the broadcast
 * @param requestCode    Private request code for the sender
 * @param timeInMillis   时间开始节点
 * @param interval   持续时间
 * @param intent   Intent to be broadcast
 */
public static void setAlarmTime(Context context, int requestCode, long timeInMillis,int interval, Intent intent) {
    AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    PendingIntent sender = PendingIntent.getBroadcast(context, requestCode,
            intent, PendingIntent.FLAG_CANCEL_CURRENT);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        am.setWindow(AlarmManager.RTC_WAKEUP, timeInMillis, interval, sender);
    }
}
/**
 * Alarm 取消
 * @param context
 * @param action
 * @param requestCode
 */
public static void cancelAlarm(Context context, String action, int requestCode) {
    Intent intent = new Intent(action);
    PendingIntent pi = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent
            .FLAG_CANCEL_CURRENT);
    AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    am.cancel(pi);
}</span>






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值