相信你們在項目裏面很多會用到倒計時操做吧,倒計時功能在咱們業務開發中使用機率很是高,例如用戶操做姿式錯誤,咱們給一個提示,提示是帶有倒計時的對話框,固然你會問爲何不直接用Toast呢?java
確實,咱們能夠直接用土司,可是每每這不是產品想要的,他們以爲沒有交互,體驗不好,再例如咱們用戶完成某個任務也能夠經過這種倒計時框給用戶提醒,倒計時操做再android開發需求很普遍,這裏就很少說。android
在andriod中倒計時的實現也有不少種,你能夠經過最經常使用的Handler+Thread方式實現,也能夠經過Timer方式實現,固然也能夠經過本章要介紹的Google官方推薦的CountDownTimer來實現,固然解決問題的方式又不少,不只僅就這幾種方法,這幾種只是個衆多方法中的表明,像Handler實現倒計時還有不少變種,例如很Message搭配方式,跟Runnable結合使用方式等等,總之,歸根結底都是在子線程進行耗時操做,在UI線程進行更新。函數
那麼如今咱們分別介紹這幾種不一樣的方式:oop
先上碼再說:ui
正如你們所見咱們在主線程中建立一個Handler,經過handler機制來更新咱們的UI,這裏更新UI是指咱們展現給你們看的倒計時,這裏我只介紹倒計時的邏輯和實現,具體應用在什麼場景你們本身發揮吧,你能夠展現在一個TextView上,也能夠彈出一個對話框看成提示,這裏咱們對倒計時的載體忽略,你們關心倒計時的邏輯並根據狀況移植到本身的案例中。google
咱們在主線程中(即ui線程)建立一個handler,這裏咱們用到handler消息機制,不明白的能夠去看這篇文章www.jianshu.com/p/138363a97…線程
在handler中對控件更新內容,這裏指秒數,再自減向下循環,而後經過handler將消息發送出去,是經過handler.sendEmptyMessageDelayed(0,1),第一個參數是延遲時間,第二個參數是時間間隔,當second小於0的時候,這時候倒計時完畢,咱們就必須取消發送,經過removeCallbacksAndMessages()方法,否則handler會內存泄漏致使程序崩潰,就這樣完了??? 彷佛咱們還肯定什麼,對,一開始咱們就在handler中處理MessageQueue中的消息,可是第一條消息來自哪兒? 好像沒找到,沒錯,這裏我省略掉了咱們第一條消息這個引子,再次上圖:cdn
這裏的show方法你們能夠不用關心,由於我這裏倒計時放在對話彈框裏面,屬於對話框的邏輯,你們能夠調用new Thread(new MyThread()).start()直接開啓咱們的倒計時,這就是handler的實現倒計時,熟悉Handler機制的同窗理解起來應該沒問題。blog
這種方式跟上一種區別在於handler是在oncreate()中建立的(initView()在onCreate()方法中),activity建立的時候會調用生命週期函數完成其整個生命過程,在onCreate中會建立hanlder,而後經過obtainMessage()建立Message,最後經過sendEmptyMessage()將消息發送出去,這裏message咱們只是建立可是空的,由於咱們不須要攜帶消息到UI線程,因此咱們向MessageQueue發送一條新消息,而後handler進入循環狀態,線程內部Looper開始輪詢不斷從MwssageQueue中取出消息分發給handler處理,知道全部消息處理完,handler再也不發送消息爲止,這個過程業務層面的實現也就是handleMessage()中的邏輯,咱們在handler初始化的時候能夠設定一個倒計時時長——mLimitTime,在oncreate()中就發送一條空消息讓handler循環起來,每一次處理消息時候對時長mLimitTime進行判斷,在對應的控件上更新當前時長,不要忘了mLimitTime--,不斷循環直到咱們時長等於0也就是else流程,這裏我回調對話框dismiss()方法,在這個方法裏面咱們須要removeCallbacksAndMessages()取消咱們的handler機制,防止出現內存泄漏,跟方式1邏輯上沒有太大的差異,主要熟悉handler機制。繼承
不過這種方式我用的是Kotlin實現的,若是第一次接觸Kotlin的可能看起來不是很舒服,可是對於會Java的人來講應該不是太大問題,你也能夠根據這個邏輯用java實現這個倒計時。
例外使用Timer和TimerTask也是很簡單,用法很固定,因此你們直接根據模板調用就行,首先咱們在類初始化的時候建立好Timer和TimerTask,這個和Handler用法很類似,task的內部咱們是經過runOnUiThread()方式在ui線程更狀態,循環邏輯也是差很少,當咱們倒數計時長recLen等於0的時候咱們就cancel()取消Timer操做,這和handler的removecallbackandMessage()差很少,後面的Intent你們直接能夠忽略,這個是針對業務的邏輯,而後準備工做都完成後,咱們在onFinishCreateView()中經過schedule(task,0,1000)開啓這個task,這個和使用handler機制中的sendEmptyMessage()做用是同樣的,這裏的onFinishCreateView()方法也是業務需求方法,你們能夠把task.schedule()放到onCreate()或者onResume()啓動方法中,開啓任務並進行循環,直到條件不合理跳出循環,期間每次循環都更新控件內容。
是否是很簡單!!!!
那咱們來看一看google究竟是如何來封裝這一款倒計時的
構造方法:
millisInFuture:倒計時時長,
countDownInterval:倒計時時間隔
首先會對millisInFuture合理判斷,倒計時不合理就直接finish掉,mStopTimeInFuture=SystemClock.elapsedRealtime()+mMillisInFuture獲取倒計時終止完成時間,是什麼意思呢? 先拿到們系統當前時長,而後再加上咱們倒計時時長,至關於再代碼中對終止時間作了一個標記mStopTimeInFuture,接着看,是否是出現很熟悉的代碼——sendMessage(),原來CountDownTime內部已經爲咱們封裝好了handler機制,怪不得Google很是推薦得方式,避免開發者開發過程當中姿式使用不對致使內存泄漏引起程序崩潰,接着繼續看源碼
這裏就是處理消息的邏輯,首先google爲了程序的健壯性和一致性爲當前倒計時任務進行枷鎖,你們看這段代碼:final longmillisLeft=mStopTimeInFuture-SystemClock.elapsedRealtime(); 每次從消息隊列中取出消息都會計算剩下時長,一樣對剩下時長進行合理判斷,有一點須要注意,onTick(millisLeft)這是個啥東西,好像是個回調方法,確實google爲咱們抽象了兩個比較經常使用的回調方法,當咱們沒執行一個時間間隔後,就會調用這個回調方法更新咱們控件狀態等操做,接着看:
沒錯,內部不斷循環發送消息,handler的用法主要就是這些,無非是google替咱們封裝好了邏輯,同理直到millisLeft等於0回調onFinish()方法
上面咱們將源碼簡單過了一下,下面咱們繼續貼代碼,看看該怎麼用:
onFinish()和onTick()方法你能夠自由發揮,根據需求來執行邏輯,
其實有個更簡單作法,直接new出一個CountDownTimer()並start這個倒計時就ok了 ,而後在回調裏面進行UI更新操做,不用在定義一個TimeCount,之因此這樣寫由於擴展性好。
到此,咱們介紹的幾種倒計時基本結束了,說來講去無非就是handler的用法以及對其進行的封裝,還不是很瞭解handler的寶寶去看一下handler的文章,暫時就先到這了,祝你們週末愉快喲!!!