Android之AlarmManager
2016-05-30 10:31
429 查看
本文只是记录一些零碎的东西
最近项目里需要做消息的推送,大概看了一下,在手机平台上,常用的方法有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。
一个简单的以广播形式调用的封装
最近项目里需要做消息的推送,大概看了一下,在手机平台上,常用的方法有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>
相关文章推荐
- 记Android Studio自定义属性访问不了的问题
- fragement生命周期
- android Hybird开发,phonegap项目,node grunt 压缩、混淆 angularjs/ionic
- 安卓初识基本控件_Gallery
- android 仿饿了么购物车
- android auto 学习分享
- Android Studio中SVN安装与使用
- android 记事本程序源码
- 内存中加载图片防止oom措施
- android_文本垂直滚动
- Android复制asset目录的文件到SD卡下
- 15 个 Android 通用流行框架大全
- Android之自定义Adapter的ListView
- Android禁用横竖屏切换那些事
- Android基础之四大组件---Service(一)
- android 导入gradle项目The project is using an unsupported version of Gradle.
- Android 拍照或从相册取图片并裁剪
- android跑马灯
- Android绘图机制与处理技巧(三)——Android图像处理之图形特效处理
- Android选择图片的两种方式