Android开发中必不可少会遇到轮询或定时任务,在RxJava诞生之前,我们常常使用Handler+postDelay,或者Java中的Timer来实现,实际上RxJava也可以实现这类需求。下面,我们将分别介绍这几种方案的实现原理。
方案一:使用Handler实现轮询。
Handler提供了postDelay方法可以延迟执行某个Runnable,如果我们在Runnable的run方法中继续将当前Runnable postDelay到Handler中,则可以实现轮询。
下面代码将会间隔1秒打印从1到10。
Handler handler = new Handler(Looper.getMainLooper()); // 全局变量
int count = 0; // 全局变量
void testCount() {
handler.postDelay(new Runnable() {
void run() {
// do something
count++;
Log.d(TAG, "count: " + count);
if (count < 10) {
handler.postDelay(this, 1000);
}
}
}, 1000);
}
原理如上,但是实际上开发过程,我们需要考虑更多,比如如何方便的取消任务,当Activity销毁时候,要及时取消任务以防止内存泄漏,或者出现其他异常导致崩溃。另外,上面代码对于每个任务都需要去手动调用postDelay,属于重复性工作。我们可以对其进行封装,抽象出轮询以及取消的接口,而不需要管内部的实现。
下面我封装一个HandlerTimer类,内部提供下面的接口:
// 延迟执行任务
public TimerTask schedule(final Runnable runnable, final long delay, final TimeUnit delayTimeUnit);
// 轮询任务
public TimerTask schedule(final Runnable runnable, final long delay, final long period, final TimeUnit timeUnit);
// 取消任务
public void cancel(TimerTask timerTask);
schedule方法一个支持延迟执行任务,一个支持轮询,两个方法都返回一个TimerTask类,这个类有个cancel方法可以取消任务执行。当然,HandlerTimer类也提供了cancel接口来取消任务。
源码如下:
public class HandlerTimer {
private Handler handler;
public HandlerTimer(Handler handler) {
this.handler = handler;
}
public TimerTask schedule(final Runnable runnable, final long delay, final TimeUnit delayTimeUnit) {
TimerTask timerTask = new TimerTask() {
@Override
public void doRun() {
runnable.run();
}
};
handler.postDelayed(timerTask, delayTimeUnit.toMillis(delay));
return timerTask;
}
public TimerTask schedule(final Runnable runnable, final long delay, final long period, final TimeUnit timeUnit) {
TimerTask timerTask = new TimerTask() {
@Override
public void doRun() {
runnable.run();
handler.postDelayed(this, timeUnit.toMillis(period));
}
};
handler.postDelayed(timerTask, timeUnit.toMillis(delay));
return timerTask;
}
public void cancel(TimerTask timerTask) {
if (timerTask != null) {
timerTask.cancel();
handler.removeCallbacks(timerTask);
}
}
public static abstract class Time