概述
最近做项目用到心跳轮询到主动到服务器取消息,为了做推送。坑了个爹的,极光百度推送限制多不能满足需求,只能自己写…手机主动到Service取数据,也就意味着你的手机要有一个服务,一直在后台运行,在特定的时间去服务器询问有没有消息,如果有消息则取回客户端。
当然还可以用像什么XMPP(当然为了一个消息推送,动用那么大而又笨重的东西,很明显不明智),短信通知等等一下方式。这里主要讲在android主动取数据:
其实实现后台推送消息给客户端可以分为主动取,和主动推两种。主动取:就是我们上面说的轮询服务器取消息。
主动推:服务器推送消息给客户端,这里必须客户端和服务器保持长连接。
两种形式各有利弊,“主动取”不能保证消息的实时性;“主动推”能保证消息的实时性,但是不能保证android端的这个链接不会被kill掉。
实现轮询
原理
其原理在于在android端的程序中,让一个SERVICE一直跑在后台,在规定时间之内调用服务器接口进行数据获取。这里的原理很简单,当然实现起来也不难;
然后,这个类之中肯定要做网络了数据请求,所以我们在Service中建立一个线程(因为在android系统中网络请求属于长时间操作,不能放主线程,不然会导致异常),在线程中和服务器进行通信。
最后,这个逻辑写完后,我们需要考虑一个问题,如何进行在规定时间内调用该服务器,当然可以用Thread+Handler(这个不是那么稳定),也可以使用AlamManager+Thread(比较稳定),因为我们需要其在后台一直运行,所以可以依靠系统的Alammanager这个类来实现,Alammanager是属于系统的一个闹钟提醒类,通过它我们能实现在规定间隔时间调用,并且也比较稳定,这个service被杀后会自己自动启动服务。
示例代码:
- 轮询service
public class PollingService extends Service {
public static final String ACTION = "com.lambertlei.Services";
private Notification mNotification;//消息通知器
private NotificationManager mManager;//消息通知管理器
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.i("result", "轮询服务被创建onCreate");
initNotifiManager();
}
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Log.i("result", "onStart");
new PollingThread().start();
}
//初始化消息管理器
private void initNotifiManager() {
// TODO Auto-generated method stub
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, MainActivity.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);
}
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() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i("result", "轮询服务销毁了");
}
}
- 轮询辅助工具类
/**
* 轮询工具类
* @author lambert_lei
*
*/
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
0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
//触发服务的起始时间
long triggerAtTime = SystemClock.elapsedRealtime();
//使用AlarmManger的setRepeating方法设置定期执行的时间间隔(seconds秒)和需要执行的Service
manager.setRepeating(AlarmManager.ELAPSED_REALTIME, triggerAtTime,
seconds * 1000, pendingIntent);
Log.i("result", "it will start weigthing 3...");
}
//停止轮询服务
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);
}
}
以上就是我们的心跳包核心类,我们通过辅助类里面的startPollingService,和stopPollingService分别来控制调起服务和停止服务。
好了,写完了…………………
最后demo下载地址:http://download.csdn.net/detail/leifengpeng/8697965
当然这个是需要积分,其实这里核心代码就够了,土豪可以给点分,哈哈。
最后
以上就是无心鸭子为你收集整理的Android心跳轮询的全部内容,希望文章能够帮你解决Android心跳轮询所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复