博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[置顶] Android AlarmManager实现不间断轮询服务
阅读量:6149 次
发布时间:2019-06-21

本文共 4628 字,大约阅读时间需要 15 分钟。

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

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

 

 

加入我们的QQ群或微信公众账号请查看:

同时欢迎关注我的新浪微博和我交流:

觉得这篇文章对你有用就顶我一下或者点击右下角分享按钮分享给更多的人!偷笑

你可能感兴趣的文章
Response. AppendHeader使用大全及文件下载.net函数使用注意点(转载)
查看>>
Wait Functions
查看>>
代码描述10313 - Pay the Price
查看>>
jQuery最佳实践
查看>>
centos64i386下apache 403没有权限访问。
查看>>
vb sendmessage 详解1
查看>>
jquery用法大全
查看>>
PC-BSD 9.2 发布,基于 FreeBSD 9.2
查看>>
网卡驱动程序之框架(一)
查看>>
css斜线
查看>>
Windows phone 8 学习笔记(3) 通信
查看>>
重新想象 Windows 8 Store Apps (18) - 绘图: Shape, Path, Stroke, Brush
查看>>
Revit API找到风管穿过的墙(当前文档和链接文档)
查看>>
Scroll Depth – 衡量页面滚动的 Google 分析插件
查看>>
Windows 8.1 应用再出发 - 视图状态的更新
查看>>
自己制作交叉编译工具链
查看>>
Qt Style Sheet实践(四):行文本编辑框QLineEdit及自动补全
查看>>
[物理学与PDEs]第3章习题1 只有一个非零分量的磁场
查看>>
深入浅出NodeJS——数据通信,NET模块运行机制
查看>>
onInterceptTouchEvent和onTouchEvent调用时序
查看>>