1. 程式人生 > >Android定時任務的實現方式

Android定時任務的實現方式

在日常的Android功能開發中,我們難免會碰到需要定時任務功能,例如定時輪詢某個介面,或者是每隔多長時間檢查一次本地資料,在本文中,主要介紹android中常用的兩種定時任務實現方式

  • 使用Handler實現
  • 使用RxJava實現
一、使用Handler實現定時任務

Handler實現定時任務的原理是通過不斷的傳送延遲訊息實現,對handler實現定時任務進行簡單封裝工具類如下:

/**
 * 輪詢工具類(Handler實現)
 */
public class PollingUtil {

    private Handler mHanlder;
    private Map<Runnable, Runnable> mTaskMap = new HashMap<Runnable, Runnable>();

    public PollingUtil(Handler handler) {
        mHanlder = handler;
    }

    /**
     * 開啟定時任務
     * @param runnable   任務
     * @param interval   時間間隔
     */
    public void startPolling(Runnable runnable, long interval) {
        startPolling(runnable, interval, false);
    }

    /**
     * 開啟定時任務
     * @param runnable   任務
     * @param interval   時間間隔
     * @param runImmediately  是否先立即執行一次
     */
    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);
    }

    /**
     * 結束某個定時任務   
     * @param runnable  任務
     */
    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<Long>() {
                            @Override
                            public void accept(Long aLong) throws Exception {
                                Log.e("MainActivity", "----------RxJava 定時輪詢任務----------");
                            }
                        });

然後可以通過呼叫Disposable 的disposable ()方法停止輪詢:

disposable.dispose();

執行結果如下:
執行結果

三、總結

以上介紹的兩種方式是專案中比較常用的實現定時任務的方式,並且在測試的過程中發現了一個很奇怪的問題,就是這兩種方式在模擬器上執行的時候都只是剛開始的回撥時間比較準確,到第四五次之後就出現很久才回調的情況,但是在真機上測試這兩種方式回撥時間都是準確的,這裡可能是模擬器出現的問題。