在日常的Android功能開發中,我們難免會碰到需要定時任務功能,例如定時輪詢某個接口,或者是每隔多長時間檢查一次本地資料,在本文中,主要介紹android中常用的兩種定時任務實作方式
使用Handler實作
使用RxJava實作
一、使用Handler實作定時任務
Handler實作定時任務的原理是通過不斷的發送延遲消息實作,對handler實作定時任務進行簡單封裝工具類如下:
public class PollingUtil {
private Handler mHanlder;
private Map mTaskMap = new HashMap();
public PollingUtil(Handler handler) {
mHanlder = handler;
}
public void startPolling(Runnable runnable, long interval) {
startPolling(runnable, interval, false);
}
public void startPolling(final Runnable runnable, final long interval,
boolean runImmediately) {
if (runImmediately) {
runnable.run();
}
Runnable task = mTaskMap.get(runnable);
if (task == null) {
task = new Runnable() {
@Override
public void run() {
runnable.run();
post(runnable, interval);
}
};
mTaskMap.put(runnable, task);
}
post(runnable, interval);
}
public void endPolling(Runnable runnable) {
if (mTaskMap.containsKey(runnable)) {
mHanlder.removeCallbacks(mTaskMap.get(runnable));
}
}
private void post(Runnable runnable, long interval) {
Runnable task = mTaskMap.get(runnable);
mHanlder.removeCallbacks(task);
mHanlder.postDelayed(task, interval);
}
}
開啟定時任務
//每3秒列印一次日志
PollingUtil pollingUtil = new PollingUtil(new Handler(getMainLooper()));
Runnable runnable = new Runnable() {
@Override
public void run() {
Log.e("MainActivity", "----------handler 定時輪詢任務----------");
}
};
pollingUtil.startPolling(runnable, 3000, true);
停止定時任務
pollingUtil.endPolling(runnable);
二、使用RxJava實作定時任務
RxJava實作定時任務主要通過 interval 方法:
interval(long initialDelay, long period, TimeUnit unit)
interval(long period, TimeUnit unit)
參數解釋:
initialDelay:首次執行任務延遲多少
period:定時任務時間間隔
unit:時間機關
下面代碼是實作每隔3秒列印一次日志,首次執行任務不延遲:
Disposable disposable = Observable.interval(0, 3, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
@Override
public void accept(Long aLong) throws Exception {
Log.e("MainActivity", "----------RxJava 定時輪詢任務----------");
}
});
然後可以通過調用Disposable 的disposable ()方法停止輪詢:
disposable.dispose();
運作結果如下:
三、總結
以上介紹的兩種方式是項目中比較常用的實作定時任務的方式,并且在測試的過程中發現了一個很奇怪的問題,就是這兩種方式在模拟器上運作的時候都隻是剛開始的回調時間比較準确,到第四五次之後就出現很久才回調的情況,但是在真機上測試這兩種方式回調時間都是準确的,這裡可能是模拟器出現的問題。