在消息的获取上是选择 轮询还是推送得根据实际的业务需要来技术选型,例如对消息实时性比较高的需求,比如微博新通知或新闻等那就最好是用推送了。但如果只是一般的消息检测比如 更新检查,可能是半个小时或一个小时一次,那用轮询也是一个不错的选择,因为不需要额外搭建推送服务器,不用额外配置推送服务。另外推送现在一般以维持长 连接的方式实现,在手机客户端也会耗费一定的电量。今天就介绍一个在Android上实现轮询机制的方法——使用AlarmManager

AlarmManager 在Android中主要用来定时处理一个事件或是定期处理一个事件,比如闹钟应用就是使用AlarmManager来实现的,我们今天要使用 AlarmManager的定期执行功能来实现轮询的功能。对于定期执行任务也可以用Timer和TimerTask来实现,也可以开一个Service 在Thread里面以while循环来实现。但最好的方案还是选用AlarmManager,这里涉及一个Android系统锁的机制,即系统在检测到一 段时间没有活跃以后,会关闭一些不必要的服务来减少资源和电量消耗。使用Timer和Service来实现的话很可能出现的情况就是屏幕熄灭后一段时间, 服务就被停止了,当然轮询也就被停止了。这个大家可以实验一下,之前我写过一篇文章也介绍了一种保持后台唤醒的机制《使用WakeLock使Android应用程序保持后台唤醒》,感兴趣的可以看看。那么接下来就开始使用AlarmManager+Service+Thread来实现我们的轮询服务吧!

一、新建轮询工具类PollingUtils.java

public class PollingUtils {//开启轮询服务public static void startPollingService(Context context, int seconds, Class<?> cls,String action) {//获取AlarmManager系统服务AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);//包装需要执行Service的IntentIntent intent = new Intent(context, cls);intent.setAction(action);PendingIntent pendingIntent = PendingIntent.getService(context, 0,intent, PendingIntent.FLAG_UPDATE_CURRENT);//触发服务的起始时间long triggerAtTime = SystemClock.elapsedRealtime();//使用AlarmManger的setRepeating方法设置定期执行的时间间隔(seconds秒)和需要执行的Servicemanager.setRepeating(AlarmManager.ELAPSED_REALTIME, triggerAtTime,seconds * 1000, pendingIntent);}//停止轮询服务public static void stopPollingService(Context context, Class<?> cls,String action) {AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);Intent intent = new Intent(context, cls);intent.setAction(action);PendingIntent pendingIntent = PendingIntent.getService(context, 0,intent, PendingIntent.FLAG_UPDATE_CURRENT);//取消正在执行的服务manager.cancel(pendingIntent);}
}

二、构建轮询任务执行PollingService.java

public class PollingService extends Service {public static final String ACTION = "com.ryantang.service.PollingService";private Notification mNotification;private NotificationManager mManager;@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {initNotifiManager();}@Overridepublic void onStart(Intent intent, int startId) {new PollingThread().start();}//初始化通知栏配置private void initNotifiManager() {mManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);int icon = R.drawable.ic_launcher;mNotification = new Notification();mNotification.icon = icon;mNotification.tickerText = "New Message";mNotification.defaults |= Notification.DEFAULT_SOUND;mNotification.flags = Notification.FLAG_AUTO_CANCEL;}//弹出Notificationprivate void showNotification() {mNotification.when = System.currentTimeMillis();//Navigator to the new activity when click the notification titleIntent i = new Intent(this, MessageActivity.class);PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, i,Intent.FLAG_ACTIVITY_NEW_TASK);mNotification.setLatestEventInfo(this,getResources().getString(R.string.app_name), "You have new message!", pendingIntent);mManager.notify(0, mNotification);}/*** Polling thread* 模拟向Server轮询的异步线程* @Author Ryan* @Create 2013-7-13 上午10:18:34*/int count = 0;class PollingThread extends Thread {@Overridepublic void run() {System.out.println("Polling...");count ++;//当计数能被5整除时弹出通知if (count % 5 == 0) {showNotification();System.out.println("New message!");}}}@Overridepublic void onDestroy() {super.onDestroy();System.out.println("Service:onDestroy");}}

三、在MainActivity.java中开启和停止PollingService

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//Start polling serviceSystem.out.println("Start polling service...");PollingUtils.startPollingService(this, 5, PollingService.class, PollingService.ACTION);}@Overrideprotected void onDestroy() {super.onDestroy();//Stop polling serviceSystem.out.println("Stop polling service...");PollingUtils.stopPollingService(this, PollingService.class, PollingService.ACTION);}}

四、运行效果

运行工程后可以在控制台输出看到,每隔5s就发出一个通知,退出Activity时,轮询服务就停止了,达到了我们事先期望的效果,并且锁屏后很长一段时间也不会停止服务,因为AlarmManager是系统及服务。Demo效果如下图:

在手机上我们可以看到弹出的通知信息,点击通知则进到消息界面:

                            

当进入消息详情Activity时,顶部状态栏的消息通知就会取消,使用如下方式也可以取消状态栏顶部的消息通知显示:

NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);manager.cancelAll();

以上就实现了使用AlarmManger实现轮询的一种方式,有不足或缺陷的地方欢迎大家留言补充,以上代码只是部分,需要工程源码的同学可以到Github上Clone:https://github.com/tangren03/RTPollingDemo

Android AlarmManager实现不间断轮询服务相关推荐

  1. Android学习系列(7)--App轮询服务器消息

    这篇文章是android开发人员的必备知识. 1.轮询服务器      一般的应用,定时通知消息可以采用轮询的方法从服务器拿取消息,当然实时消息通知的话,建议采用推送服务.     其中需要注意轮询的 ...

  2. 利用AlarmManager完成精准的轮询

    问题分析 想起轮询我们一般会想起利用Handler和Timer,然而AlarmManager相比于Handler和Timer有优势,具体的分析我参考了一个大神的博客: 最近在做一个需求:客户端按照规定 ...

  3. android 常驻轮询服务,Android实现自动轮询的RecycleView

    需求:类似医院或者商场,大屏幕无限轮播item (广告词/广告图-),供大家参考,具体内容如下 代码如下 /** * Created by Xia_焱 on 2017/8/20. */ public ...

  4. Android 轮询最佳实践 Service + AlarmManager+Thread

    为什么80%的码农都做不了架构师?>>>    android中涉及到将服务器中数据变化信息通知用户一般有两种办法,推送和轮询. 消息推送是服务端主动发消息给客户端,因为第一时间知道 ...

  5. Android 轮询最佳实践 Service + AlarmManager

    为什么80%的码农都做不了架构师?>>>    虽然alarm的意思是闹钟,而且在原生android自带的闹钟应用中AlarmManager也确实非常重要,但并不代表AlarmMan ...

  6. android全局轮询机制,Android轮询机制

    在消息的获取上是选择轮询还是推送得根据实际的业务需要来技术选型,例如对消息实时性比较高的需求,比如微博新通知或新闻等那就最好是用推送了.但如果只是一般的消息检测比如更新检查,可能是半个小时或一个小时一 ...

  7. Android 项目必备(十一)--> 轮询操作

    文章目录 前言 实战 前言 什么叫轮询请求? 简单理解就是 App 端每隔一定的时间重复请求的操作就叫做轮询请求,比如:App 端每隔一段时间上报一次定位信息,App 端每隔一段时间拉去一次用户状态等 ...

  8. java 实现http长轮询,Long Polling长轮询实现进阶

    Long Polling长轮询实现进阶 简书 涤生. 转载请注明原创出处,谢谢! 如果读完觉得有收获的话,欢迎点赞加关注. 介绍 由于Long Polling长轮询详解 这篇文章中的code实现较为简 ...

  9. spring 实现异步非阻塞长轮询

    一. 前言 今天接到一个扫码登录的需求.想一想很简单,服务端提供一个获取二维码接口,在提供一个查询扫码状态的接口,客户端不停轮询"查询扫码状态接口"判断用户是否已扫码登录,并很快实 ...

最新文章

  1. python while循环语句-Python
  2. php 补足字符串,php 数目字或者字符串补全
  3. 使用Python的随机数模块 random 实现猜数字游戏
  4. SAP CRM SPRO Customizing 里 Text Object 属性 continue 的含义
  5. mysql 删除用户变量_MySql安装与MySQL添加用户、删除用户与授权
  6. Natasha 4.0 探索之路系列(四) 模板 API
  7. Leetcode--279. 完全平方数
  8. python基础之玩转(变量赋值)
  9. NOIP2018赛前停课集训记——最后的刷板子计划
  10. Mysql 远程自动化备份
  11. App列表之拖拽ListView(上)
  12. Spring MVC 实现文件的上传和下载
  13. 创建触发器报错_Oracle行级触发器的使用
  14. SQL Server各版本官方下载地址
  15. 粒子特效 代码(龙卷风)
  16. 一套成熟的BPM系统应该有的功能
  17. 题解 P4147 【玉蟾宫】
  18. vmware虚拟机镜像制作成QCOW2
  19. 《今雨》孙溟㠭书画艺术
  20. uva10306(dp)

热门文章

  1. VC++多线程工作笔记0004---线程相关操作
  2. Web前端工作笔记001---封装前端数据字典_js 数组filter 总结_详解
  3. fckeditor组件使用---fckeditor调用的三种方法1
  4. 跑通im2txt 程序(1)
  5. javascript图片库威力增强版
  6. php将文件转换为utf-8,PHP-将邮件正文转换为UTF-8
  7. 学生信息管理系统c 语言程序设计报告,C语言程序设计报告(学生信息管理系统)[1].txt...
  8. 3d激光雷达开发(八叉树)
  9. 红旗linux系统可以运行QQ吗,如何在红旗Linux系统redflag6.0上安装QQ
  10. kali linux 网络命令,Kali Linux系统连接Wifi无线网络命令: