android开发分享andriod如何搭建自己的轮询框架

很多时候android应用需要每间隔一段时间向服务器请求数据,如果服务器数据有更新则通知界面变化。android中最常用的红点一般采用的就是轮询,红点是为了在数据有更新时及

很多时候android应用需要每间隔一段时间向服务器请求数据,如果服务器数据有更新则通知界面变化。android中最常用的红点一般采用的就是轮询,红点是为了在数据有更新时及时的提醒用户,比如朋友圈更新,当用户的朋友圈更新时就会显示红点,就是通过移动端不断的向服务器查询朋友圈的更新状态。

相关知识点

在实现轮询框架时会主要会要到下面两个类,会结合轮询框架对这三个类进行讲解,在应用中分析会理解更加深刻。

1、intentservice intentservice是一种特殊的service,继承了service并且是一个抽象类,必须创建它的子类才能用。intentservice可以用于执行后台耗时的任务,当任务执行后会自动停止,intentservice的优先级比一般的线程高,比较适合执行一些优先级高的后台任务。

2、pendingintent pendingintent是延迟的intent,主要用来在某个事件完成后执行特定的action。pendingintent包含了intent及context,所以就算intent所属程序结束,pendingintent依然有效,可以在其他程序中使用。pendingintent一般作为参数传给某个实例,在该实例完成某个操作后自动执行pendingintent上的action,也可以通过pendingintent的send函数手动执行,并可以在send函数中设置onfinished表示send成功后执行的动作。

轮询框架实现

要实现轮询,可以借鉴handler中的looper机制,如下图,维护一个消息队列,循环的从消息队列中取出消息来执行,轮询框架可以定时的向消息队列中加入消息,然后循环中消息队列中取出消息执行。

andriod如何搭建自己的轮询框架

可以自己实现一个looper,但是intentservice中已经包含了一个looper和一个handlerthread。因此轮询框架中使用intentservice作为循环框架。继承intentservice接口来实现处理消息访问服务器。

pollingservice 用于每次轮询时向请求服务器接口数据。

  public class pollingservice extends intentservice {  	public static final string action_check_circle_update="action_check_circle_update";	  	public static final long default_min_polling_interval = 60000;//最短轮询间隔1分钟   public pollingservice() {    super("pollingservice");   }  	   @override   protected void onhandleintent(intent intent) {    if (intent == null)     return;    final string action = intent.getaction();    if (action_check_circle_update.equals(action)) {     checkcircleoffriendsupdate();//这个是访问服务器获取朋友圈是否更新    }   }  }

pollingservice 用来处理接到轮询的消息之后在 onhandleintent(intent intent) 中根据intent所带有的action不同来进行访问服务器不同的接口获取数据。

pollingutil 用于控制轮询服务的开始和结束 使用pollingutil中的startpollingservice来根据action和context生成一个pendingintent,并将pendingintent交给pollingscheduler来处理。pollingscheduler是一个线程池控制类。

  public class pollingutil {   /**    * 开始轮询服务    */   public static void startpollingservice(final context context, string action) {     //包装需要执行service的intent     intent intent = new intent(context, pollingservice.class);     intent.setaction(action);     pendingintent pendingintent = pendingintent.getservice(context, 0,       intent, pendingintent.flag_update_current);     pollingscheduler.getinstance().addscheduletask(pendingintent, 0, pollingservice.default_min_polling_interval);    }   }   /**    * 停止轮询服务    *    * @param context    */   public static void stoppollingservices(context context, string action) {     pollingscheduler.getinstance().clearscheduletasks();    }   }

pollingscheduler实现定时向intentservice的looper中加入消息 pollingscheduler中生成一个单线程池,addscheduletask中定时的执行pendingintent.send(),其中pendingintent是由 pendingintent pendingintent = pendingintent.getservice(context, 0,intent, pendingintent.flag_update_current); 生成的,pendingintent.send()函数会调用service.startservice()来开启一个服务。

  public class pollingscheduler {   private static pollingscheduler sinstance;   private scheduledexecutorservice mscheduler;     private pollingscheduler() {    mscheduler = executors.newsinglethreadscheduledexecutor();   }     public static synchronized pollingscheduler getinstance() {    if (sinstance == null) {     sinstance = new pollingscheduler();    }    if (sinstance.mscheduler.isshutdown()) {     sinstance.mscheduler = executors.newsinglethreadscheduledexecutor();    }    return sinstance;   }  	   public void addscheduletask(final pendingintent pendingintent, long initialdelay, long period) {    runnable command = new runnable() {     @override     public void run() {      try {       pendingintent.send();      } catch (pendingintent.canceledexception e) {       e.printstacktrace();      }     }    };    mscheduler.scheduleatfixedrate(command, initialdelay, period, timeunit.milliseconds);   }     public void clearscheduletasks() {    mscheduler.shutdownnow();   }  }

代码分析

先给出类图之间的关系如下:

andriod如何搭建自己的轮询框架 

pollingservice继承了intentservice,并且在pollingutil的startpollingservice方法中通过 intent intent = new intent(context, pollingservice.class); 和将pendingintent 与pollingservice关联起来,并将pendingintent加入到定时执行的线程池中,在pollingscheduler 中使用 pendingintent.send();

由于pendingintent与pollingservice关联,所以执行pendingintent.send()的时候会调用pollingintentservide中的onstart()方法。onstart()方法是intentservice中的方法,代码如下:

   @override   public void onstart(@nullable intent intent, int startid) {    message msg = mservicehandler.obtainmessage();    msg.arg1 = startid;    msg.obj = intent;    mservicehandler.sendmessage(msg);   }

在onstart()中有一个 mservicehandler.sendmessage(msg); ,找到mservicehandler的生成位置:

   @override   public void oncreate() {    super.oncreate();    handlerthread thread = new handlerthread("intentservice[" + mname + "]");    thread.start();      mservicelooper = thread.getlooper();    mservicehandler = new servicehandler(mservicelooper);   }

在intentservice的oncreate方法中生成了一个handlerthread,一个mservicelooper,一个mservicehandler,其中mservicehandler.sendmessage(msg)中的msg都会放到mservicelooper,执行时从mservicelooper中取出执行,其中servicehandler 的代码如下

   private final class servicehandler extends handler {    public servicehandler(looper looper) {     super(looper);    }      @override    public void handlemessage(message msg) {     onhandleintent((intent)msg.obj);     stopself(msg.arg1);    }   }

handlemessage(message msg)中会调用onhandleintent((intent)msg.obj);方法,也就是在pollingservice中重写的onhandleintent方法。 因此我们在addscheduletask中不断的执行pending.send()方法,会不断的调用intentservice中的onstart方法中的mservicehandler.sendmessage(msg);不断的向消息队列中发消息,然后在onhandleintent处理消息。 这样一个轮询框架就完成了。

总结

android开发分享andriod如何搭建自己的轮询框架的轮询框架利用了intentservice中的handler和looper机制来实现循环的处理消息,由于intentservice具有服务的特性因此特别适合后台轮询访问服务器数据。

以上就是android开发分享andriod如何搭建自己的轮询框架的全部内容,希望对大家的学习有所帮助,也希望大家多多支持<计算机技术网(www.ctvol.com)!!>。

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/addevelopment/901949.html

(0)
上一篇 2021年10月24日
下一篇 2021年10月24日

精彩推荐