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

Intent 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秒)和需要执行的Service

manager.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;

@Override

public IBinder onBind(Intent intent) {

return null;

}

@Override

public void onCreate() {

initNotifiManager();

}

@Override

public 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;

}

//弹出Notification

private void showNotification() {

mNotification.when = System.currentTimeMillis();

//Navigator to the new activity when click the notification title

Intent 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 {

@Override

public void run() {

System.out.println("Polling...");

count ++;

//当计数能被5整除时弹出通知

if (count % 5 == 0) {

showNotification();

System.out.println("New message!");

}

}

}

@Override

public void onDestroy() {

super.onDestroy();

System.out.println("Service:onDestroy");

}

}

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

public class MainActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//Start polling service

System.out.println("Start polling service...");

PollingUtils.startPollingService(this, 5, PollingService.class, PollingService.ACTION);

}

@Override

protected void onDestroy() {

super.onDestroy();

//Stop polling service

System.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全局轮询机制,Android轮询机制相关推荐

  1. Android全局修改字体大小,Android 仿微信全局字体大小调整

    image 目录 一.前言 二.效果预览 三.实现步骤 1.自定义字体调整控件 2.滑动按钮改变当前页面预览字体大小 3.返回时,保存放大倍数并重启应用 4.初始化应用时配置字体放大倍数. 四.Dem ...

  2. android 全局定时器,高通Android LED驱动移植-GPIO,内核定时器

    有些设备需要有灯的闪烁来表达一些含义,比如电池电量.利用GPIO实现灯的灭.亮.慢闪.快闪需要配合内核定时器来实现. 首先我们找到高通内核自带的LED相关的文件, /kernel/driver​s/l ...

  3. android全局监听onkeydown,Android中的几个onTouch()事件、onKeyDown监听返回键无效

    Android中的几个onTouch()事件.onKeyDown监听返回键无效 一:Android中的几个onTouch()事件 继承SimpleOnGestureListener,HahaGestu ...

  4. android全局的dialog,使android的dialog全局显示

    1.上下文传applicationContent类型的 2.添加dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_AL ...

  5. android 炫酷的自定义轮播图,Android实现炫酷轮播图效果

    轮播图的实现有很多种方式,早先我在网上看了下别人写的轮播图,感觉都比较的墨守成规,有的还有可能加载不了网络图片.所以我在这里自己重新写了下轮播图 ,方便日后的项目使用. 在下面的代码中,我也用voll ...

  6. 服务器推送技术之短轮询、长轮询、SSE和Websocket

    服务器推送技术 服务器推送技术干嘛用?就是让用户在使用网络应用的时候,不需要一遍又一遍的去手动刷新就可以及时获得更新的信息.大家平时在上各种视频网站时,对视频节目进行欢乐的吐槽和评论,会看到各种弹幕, ...

  7. 长连接、短连接、短轮询、长轮询

    长连接.短连接.短轮询.长轮询 短连接:每次Http请求都会建立Tcp连接,管理容易 长连接:只需要建立一次Tcp连接,以后Http请求重复使用同一个Tcp连接,管理难 短轮询:重复发送Http请求, ...

  8. Android——开源框架Universal-Image-Loader + Fragment使用+轮播广告

    原文地址: Android 开源框架Universal-Image-Loader完全解析(一)--- 基本介绍及使用 Android 开源框架Universal-Image-Loader完全解析(二) ...

  9. 转---谈谈HTTP协议中的短轮询、长轮询、长连接和短连接

    作者:伯乐在线专栏作者 - 左潇龙 http://web.jobbole.com/85541/ 如有好文章投稿,请点击 → 这里了解详情 引言 最近刚到公司不到一个月,正处于熟悉项目和源码的阶段,因此 ...

  10. 轮询、长轮询与Web Socket的前端实现

    Web Socket 应用场景:实现即时通讯:如股票交易行情分析.聊天室.在线游戏等,替代轮询和长轮询 轮询 轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,然后由 ...

最新文章

  1. 浅谈无缓存I/O操作和标准I/O文件操作区别 (转载)
  2. 华为UPS“内外”兼修
  3. u盘读写测试_如何提高u盘读写速度 提高u盘读写速度方法【详细步骤】
  4. java swing实现简单图片显示(测试生成图片快捷方式)
  5. node.js 初体验
  6. 常见的锁策略、synchronized中的锁优化机制
  7. JavaScript将焦点设置为HTML表单元素
  8. 不忘初心,不负韶华——2021年中会议发言之一
  9. 谐波小波 matlab,基于谐波小波的电力系统谐波分析
  10. 环境影响评价概论期末试题重点考点
  11. 计算机专业y9000x,LEGION Y9000X笔记本U盘一键重装Win10专业版的教程
  12. oracle dbf文件迁移,Oracle安装盘空间不足,对.DBF文件进行迁移
  13. Leetcode——495. Teemo Attacking
  14. 反向迭代器---迭代器适配器
  15. maven 安装jar 及 下载jar地址
  16. 花 10 分钟看一看,少走 30 年弯路
  17. 卸载CUDA,安装pytorch
  18. 每个骰子的面数之和的次数
  19. 抓包工具charles的使用
  20. 加壳软件的实现原理篇

热门文章

  1. 个体户组织形式怎么填
  2. 百圣软件与金蝶云星辰系统对接方案(云星辰管库存)
  3. vscode按下ctrl键,点击鼠标别名跳转
  4. Chrome修改User Agent插件推荐
  5. OpenDDS工具之三(inspect)
  6. 情感分析 | 一份就职宣誓也许就可以预测一个国家未来几年的政治形势
  7. 广东省计算机应用专业综合理论知识,计算机应用专业综合理论考试大纲.doc
  8. 关于共享文件夹的使用
  9. Android安全 通信篇(二)
  10. java生成文件夹_java 创建文件夹和文件 汇总