在開發倒計時功能時往往我們會為了方便直接使用CountDownTimer或者使用Handler做延時來實現,當然CountDownTimer內部封裝也是使用的Handler。
如果只是做次數很少的倒計時或者不需要精確的倒計時邏輯那倒沒關系,比如說我只要倒計時10秒,或者我大概5分鐘請求某個接口
但是如果是需要做精確的倒計時操作,比如說手機發送驗證碼60秒,那使用現有的倒計時方案就會存在問題。可能有些朋友沒有註意到這壹點,下面我們就來簡單分析壹下現有倒計時的問題。
這個可能是用得最多的,因為方便嘛。但其實倒計時每壹輪倒計時完之後都是存在誤差的,如果看過CountDownTimer的源碼妳就會知道,他的內部是有做 校準操作 的。(源碼很簡單這裏就不分析了)
但是如果妳認真的測試過CountDownTimer,妳就會發現,即便它內部有做校準操作,他的沒壹輪都是有偏差,只是他最後壹次倒計時完之後的總***時間和開始倒計時的時間相比沒偏差。
什麽意思呢,意思就是1秒,2.050秒,3.1秒......,這樣的每輪偏差,導致他會出現10.95秒,下壹次12秒的情況,那它的回調中如果妳直接做取整就會出現少壹秒的情況,但實際是沒少的。
這只是其中的壹個問題,妳可以不根據它的回調做展示,自己用壹個整形累加做展示也能解決。但是他還有個問題,有概率直接出現跳秒,就是比如3秒,下次直接5秒,這是實際的跳秒,是少了壹次回調的那種。
跳秒導致妳如果直接使用它可能會大問題,妳可能自測的時候沒發現,到時壹上線應用在用戶那概率跳秒,那就蛋疼了。
不搞這麽多花裏胡哨的,直接使用Handler來實現,會有什麽問題。
因為直接使用handler來實現,沒有校準操作,每次循環會出現幾毫秒的誤差,雖然比CountDownTimer的十幾毫秒的誤差要好, 但是在基數大的倒計時情況下誤差會累計,導致最終結果和現實時間差幾秒誤差,時間越久,誤差越大
直接使用Timer也壹樣,只不過他每輪的誤差更小,幾輪才有1毫秒的誤差,但是沒有校準還是會出現誤差累計,時間越久誤差越大。
既然無法直接使用原生的,那我們就自己做壹個。
我們基於Handler進行封裝,從上面可以看出主要為了解決兩個問題,時間校準和跳秒。自己寫壹個CountDownTimer
思路就是在倒計時開始前獲取壹次SystemClock.elapsedRealtime(),沒輪倒計時再獲取壹次SystemClock.elapsedRealtime()相減得到誤差,根據delay校準。然後使用while循壞來處理跳秒的操作,與原生的CountDownTimer不同,這裏如果跳了多少秒,就會返回多少次回調。