andriod 搭建自己的轮询框架,flutter 开发环境
}
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() {@Overridepublic void run() {try {pendingIntent.send();} catch (PendingIntent.CanceledException e) {e.printStackTrace();}}};mScheduler.scheduleAtFixedRate(command, initialDelay, period, TimeUnit.MILLISECONDS);}
public void clearScheduleTasks() {mScheduler.shutdownNow();}}
代码分析
先给出类图之间的关系如下:
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 中的方法,代码如下:
@Overridepublic 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 的生成位置:
@Overridepublic 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);}
@Overridepublic 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 处理消息。 这样一个轮询框架就完成了。
总结
本文的轮询框架利用了 IntentService 中的 handler 和 Looper 机制来实现循环的处理消息,由于 IntentService 具有服务的特性因此特别适合后台轮询访问服务器数据。
更改
经过评论区的提醒,又测试了几遍发现每次轮询确实都会新建和销毁 IntentService,这样就没有利用到消息队列,所以重写了一个 PollingIntentService 类继承 Service,使得每次使用时不会重写创建 Service,达到复用的效果。同时增加了 enterPollingQueue()方法,可以直接往 PollingIntentService 的队列中增加轮询的 Intent 消息。 PollingIntentService 代码
Created time 11:40.
@author huhanjun
@since 2019/1/7*/public abstract class PollingIntentService extends Service {private volatile Looper mServiceLooper;private volatile ServiceHandler mServiceHandler;p
rivate String mName;private boolean mRedelivery;
private final class ServiceHandler extends Handler {public ServiceHandler(Looper looper) {super(looper);}
@Overridepublic void handleMessage(Message msg) {onHandleIntent((Intent) msg.obj);}}
public PollingIntentService(String name) {super();mName = name;}
@Overridepublic void onCreate() {super.onCreate();Log.d(TAG, "onCreate");HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");thread.start();mServiceLooper = thread.getLooper();mServiceHandler = new ServiceHandler(mServiceLooper);}//进入轮询队列 public void enterPollingQueue(@Nullable Intent intent, int startId) {Log.d(TAG, "enterPollingQueue");Message msg = mServiceHandler.obtainMessage();msg.arg1 = startId;msg.obj = intent;mServiceHandler.sendMessage(msg);}
@Overridepublic int onStartCommand(@Nullable Intent intent, int flags, int startId) {Log.d(TAG, "onStartCommand");enterPollingQueue(intent, startId);return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;}//停止服务 public void onStopService() {stopSelf();}
@Overridepublic void onDestroy() {mServiceLooper.quit();Log.d(TAG, "onDestroy");}
@Override@Nullablepublic IBinder onBind(Intent intent) {return null;}
评论