android 定時器(Handler Timer Thread AlarmManager CountDownTimer)


Android實現定時任務一般會使用以上(Handler Timer Thread AlarmManager CountDownTimer)五種方式。當然還有很多組合使用(比如Handler+Thread 比如Handler類自帶的postDelyed 比如Handler+Timer+TimerTask)的方式就不一一說明了,知道了每個小部分的使用結合起來使用當然就不是問題啦。

本文以簡單的實現1s讓數字加1的一個小實例。(考慮只點擊一次的情況。連續點擊 需要控制沒有結束的時候 不許點擊的邏輯)

一:使用Handler:

 private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if(msg.what == 1){
                Log.e(TAG,"mHandler"+Thread.currentThread().getName());
                tvNum.setText((Integer.parseInt(tvNum.getText().toString())+1)+"");
                mHandler.sendEmptyMessageDelayed(1,1000);
            }
        }
    };

在點擊事件的時候 調用 mHandler.sendEmptyMessageDelayed(1,1000);可以使用   mHandler.removeMessages(1);取消handler。

二:使用Timer。使用Timer的時候要用到TimerTask。也是很簡單的使用:

private void timer() {
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                Log.e(TAG, "Timer:"+Thread.currentThread().getName());
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tvNum.setText((Integer.parseInt(tvNum.getText().toString())+1)+"");
                    }
                });
            }
        }, 1000, 1000);
    }

點擊的時候就直接調用這個方法就好了。前面一個1000表示多久之后開始執行。后面的1000表示多久執行一次。其他的同名重載函數。看方法名就知道每個函數的作用了。

三:使用Thread,使用這個個人感覺和Timer差不多。都是開一個線程+延時操作。所以更新UI的時候必須在主線程。

 private MyThread thread;
    private class MyThread extends Thread {
        public boolean stop;
        public void run() {
            while (!stop) {
                // 通過睡眠線程來設置定時時間
                try {
                    Thread.sleep(1000);
                    Log.e(TAG, "Thread:"+Thread.currentThread().getName());
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            tvNum.setText((Integer.parseInt(tvNum.getText().toString())+1)+"");
                        }
                    });
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
    };
    private void startThread() { //開始線程
        if (thread == null) {
            thread = new MyThread();
            thread.start();
        }
    }
    private void stopThread() { //結束線程
        if (thread != null) {
            thread.stop = true;
            thread = null;
        }
    }

點擊時間調用startThread()就好了。

四:使用alarmService。其實通過AlarmManager來實現的。AlarmManager在安卓中最常見使用的地方就是鬧鍾。看這個的名字就知道是啟動一個系統級服務來完成的。貼代碼:

  private String ACTION_NAME = "alarmService";
    private void alarmServiceStart(){
        //注冊廣播
        registerBoradcastReceiver();
        //啟動AlarmManager
        Intent intent =new Intent(ACTION_NAME);
        PendingIntent sender=PendingIntent
                .getBroadcast(this, 0, intent, 0);
        long firstime= SystemClock.elapsedRealtime();
        AlarmManager am=(AlarmManager)getSystemService(ALARM_SERVICE);
        //5秒一個周期,不停的發送廣播
        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP
                , firstime,1000, sender);
    }
    //注冊廣播
    public void registerBoradcastReceiver(){
        IntentFilter myIntentFilter = new IntentFilter();
        myIntentFilter.addAction(ACTION_NAME);
        registerReceiver(mBroadcastReceiver, myIntentFilter);
    }
    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver(){
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if(action.equals(ACTION_NAME)){
                tvNum.setText((Integer.parseInt(tvNum.getText().toString())+1)+"");
            }
        }
    };

五:CountDownTimer:這個其實是android封裝好的一個倒計時類。用法特別方便:如下

/**

     * 使用CountDownTimer   其實是android封裝好的 倒計時類
     * 說明這里的10*1000表示總時間 也就是10s 1000表示多久執行一次
     */
    private CountDownTimer countDownTimer = new CountDownTimer(10*1000, 1000) {
        @Override
        public void onTick(long millisUntilFinished) {
            tvNum.setText((Integer.parseInt(tvNum.getText().toString())+1)+"");
        }
 @Override
        public void onFinish() {
            tvNum.setText("執行結束");
        }
    };

總結:用法其實都是很簡單的。但是就是因為有很多種方法實現不知道使用哪一種。個人建議:

1,使用倒計時(限時特賣時間倒計時,獲取驗證碼倒計時)可以使用第五種方法實現。(不考慮自定義組件)

2,圖片的輪播,banner之類的可以使用Handler和Timer(Thread差不多)。實現定時滑動。(不考慮自定義組件)

3.使用一些對特定時間執行要求比較嚴格的時候使用alarmService。這里說明一下:Android系統鎖的機制,即系統在檢測到一段時間沒有活躍以后,會關閉一些不必要的服務來減少資源和電量消耗。使用Timer和Service來實現的話很可能出現的情況就是屏幕熄滅后一段時間,服務就被停止了,當然輪詢也就被停止了。當前輪播停止對我們影響不大。但是某種特定的情況停止了可以造成很大的損失。比如鬧鍾:停止了你還能起來嗎?

這里還有一點就是第四種am的setRepeating方法。設置類型為AlarmManager.ELAPSED_REALTIME時候 當應用休眠的時候 也不會執行定時任務。設置類型為AlarmManager.ELAPSED_REALTIME_WAKEUP的時候 就會一直執行。

以上觀點都是我的個人看法。如果有不對的地方 忘大神指教。有沒有注意到的地方也忘大神指教

附上項目的github地址 https://github.com/tozzais/AndroidTimingTest


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM