目录
轮询实现方案:
方案一: Timer + Thread
实现思路:使用timer定时执行TimerTask
缺点:如果有异步任务,下次任务开始执行时需要判断上次任务是否完成,从而导致任务间隔时间不可控。
方案二: HandlerThread
实现思路:在HandleMessage方法中执行任务,任务结束后向MessageQueue中添加延时消息
优点:如果有异步任务,只需在异步任务执行完毕后再向MessageQueue中添加延时消息,任务间隔时间可控
方案三: RxJava
实现思路: interval or repeatWhen
优点:优雅,逻辑清晰,和retrofit结合
Timer
static class CommitTimer extends TimerTask {
@Override
public void run() {
commitLock.lock();
try {
doSome(0);//网络请求
} catch (Exception ex) {
ex.printStackTrace();
} finally {
commitLock.unlock();
}
}
}
Timer timer = new Timer();
timer.schedule(new CommitTimer(), 10 * 1000, 5*60* 1000);//Teask,延时时间,轮询间隔
Handler
HandlerThread handlerThread = new HandlerThread("BackgroundService");
handlerThread.start();
handler = new Handler(handlerThread.getLooper()){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//模拟耗时任务
try {
doSome(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
//向MessageQueue中添加延时消息,5s后重复执行以上任务
handler.sendEmptyMessageDelayed(MSG_GET_COMPARE_RESULT,5000);
}
};
return new GetCompareResultBinder();
RxJava
1.Interval
mSubscrib = Observable.interval(0, POLINNG_INTERVAL_TIME, TimeUnit.SECONDS)
.flatMap(i -> doSome(0))//映射为网络请求,达到轮询的目的
.subscribe(this::showSome);//根据返回结果终止轮询
private void showSome(Data data) {
if (data.idRight()) {
mSubscrib.dispose();
}
}
Android RxJava应用:网络请求轮询(无条件) - 简书
轮询间隔时间固定,灵活性不高
2.repeatWhen
mSubscrib = doSome(0)
.repeatWhen(objectObservable -> {
Log.d(TAG, "repeatWhen");
return objectObservable
.zipWith(Observable.range(1, 5), (o, integer) -> integer)
.flatMap((Function<Integer, ObservableSource<?>>) integer ->
Observable.timer((long) POLINNG_INTERVAL_TIME * integer,
TimeUnit.SECONDS)
);
})
.takeUntil(result -> {
//takeUntil 根据返回结果结束轮询,
//不能用repeatWhen里返回error来结束轮询,
//因为这样会导致最后一次返回的数据不会被执行,直接跳转到系统的error逻辑
Log.d(TAG, "taleUntil");
return result.isRight();
})
.subscribe(this::showSome);
Android RxJava应用:网络请求轮询(有条件) - 简书
可以灵活调整轮询时间
补充: