应该根据实际业务需求在技术上选择轮询还是推送来检索消息。 例如,对于消息实时性高的需求,如发新通知或新闻等微博时最好使用推送。 但是,仅通过更新检查等常见消息检查,可能会达到半小时或每小时一次。 那使用轮询也是个不错的选择。 因为不需要额外构建推送服务,也不需要额外配置推送服务。 另外,推送目前一般是通过维持长连接的方式实现的,手机客户端也会消耗一定的电力。 今天介绍如何使用AlarmManager实现Android轮询机制——
在Android中,警报管理器主要用于定期处理事件或定期处理事件。 例如,闹钟APP定是使用警报管理器实现的,今天使用警报管理器的定期执行功能实现轮询功能。 定期任务的执行也可以通过Timer和TimerTask来实现,也可以打开Service在Thread中通过while循环来实现。 但是,最好的方法是选择警报管理器。 这里涉及到安卓系统锁定机制。 这意味着在检测到系统在一段时间内不活动后,关闭不需要的服务器以减少资源和能耗。 使用Timer和Service实现的话,画面消失后一段时间服务就会被停止,当然轮询也很有可能被停止。 这个请实验一下。 以前我写的文章中也介绍了维持后台唤醒的机制《使用WakeLock使Android应用程序保持后台唤醒》,感兴趣的人请看。 现在,让我们使用警报管理器服务实践来实现轮询服务。
一.新的轮询工具类PollingUtils.java
公共类轮询实用程序{
//打开轮询服务
publicstaticvoidstartpollingservice (上下文上下文,int seconds,Class cls,String action ) {
接受警报管理器系统服务
警报管理器=(警报管理器)上下文
. getsystemservice (context.alarm _ service;
//程序包需要运行服务的Intent
intentintent=newintent(context,cls );
intent.set操作(操作;
pendingintentpendingintent=pending intent.getservice (上下文,0,
intent,pending intent.flag _ update _ current;
//触发服务的开始时间
longtriggerattime=system clock.elapsed real time (;
使用警报管理器设置报告方法设置定期运行的间隔(秒)和运行的服务
manager.set repeating (alarm manager.elapsed _ real time,triggerAtTime,
seconds * 1000,pendingIntent;
}
//停止轮询服务
publicstaticvoidstoppollingservice (上下文上下文,Class cls,String action ) {
警报管理器=(警报管理器)上下文
. getsystemservice (context.alarm _ service;
intentintent=newintent(context,cls );
intent.set操作(操作;
pendingintentpendingintent=pending intent.getservice (上下文,0,
intent,pending intent.flag _ update _ current;
//取消正在运行的服务
manager.cancel(pendingintent );
}
}
二.生成轮询任务并运行PollingService.java
publicclasspollingserviceextendsservice {
publicstaticfinalstringaction=' com.ryantang.service.polling service ';
权限通知;
权限通知管理器;
@Override
publicIbinderonbind(in
tent 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