androidtimer計時
A. android 用 service 和 CountDownTimer 實現一個倒計時器的功能
在平時我們編程的時候,經常會用到倒計時這個功能,很多人不知道Android已經幫封裝好了一個類,往往都自己寫。現在發現了這個類,大家共享一下:
在一個TextView不斷顯示剩下的時間,代碼如下:
[java] view plain
private TextView vertifyView;
private CountDownTimer timer = new CountDownTimer(10000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
vertifyView.setText((millisUntilFinished / 1000) + "秒後可重發");
}
@Override
public void onFinish() {
vertifyView.setEnabled(true);
vertifyView.setText("獲取驗證碼");
}
};
調用的時候很簡單:timer.start();
最後說明一下:CountDownTimer timer = new CountDownTimer(10000, 1000)中,第一個參數表示總時間,第二個參數表示間隔時間。意思就是每隔一秒會回調一次方法onTick,然後10秒之後會回調onFinish方法。
B. Android 定時器Timer的使用
在我們Android客戶端上有時候可能有些任務不是當時就執行,而是過了一個規定的時間在執行此次任務。那麼這個時候定時顫慧器的作用就非常有用了。首先開啟一個簡單的定時器
現在我就相當於定義了拆腔一個定時器,我現在的定時器是向伺服器發送Post請求來返回數據刷新到我的界面上那麼接下來就是開啟定時器了。開啟定時器那就非常簡單了
開啟定時器特別簡單基本上一句話就搞定了
開啟定時器需要三個參數
1.就是上面所寫的你要做的事情 ,上面我寫的上向網路發送請求那麼這里就時開啟定時器請求網路
2.這個參數是你要多長時間後執行這個定時器,這里我寫的是0,那麼就是0秒後執行我的定時器。
3.這個是最重要的這就是你每次執行時間的間隔 我這里就是說每10秒向網路發送一次請求如果寫成1000就是每一秒向網路發送一次請求
如果第三個參數不寫的話那麼定時器就是幾秒後執行 那麼定時器只執行一次就不在執行了
其實定時器如果不銷毀的話是一直執行的但其實定時器如果一直執行的話那麼我們的程序根本就撐不了多長時間就會崩潰所以說定時器用完就要及時的關閉
定時器的開啟在寫Fragment或者Activity的時候我一般會寫在onStart裡面
如果銷毀的時候會寫在onStop裡面銷毀定時器也非常簡單
基本上這一句話就搞定了執行這句話說明是注銷定時器
當我們離開本界面的時候就執行這句話那麼定時器就不會在執行了當我們進入本界面在onStart執行定時器那麼就又開啟了定時器所以說這樣就寫了一個簡易版的定時器
一個簡單的定時器請求網路就完成了 HttpHolder holder = new HttpHolder(handler); 這是自己寫的網路請旅洞衫求類直接調用輸入url的伺服器地址獲得的就是伺服器發來的JSON格式的數據
在onStop裡面注銷定時器那麼每次離開本界面的時候那麼定時候就銷毀了再回到本界面的時候那麼就執行onStart裡面的開啟定時器那麼定時器就開啟了所以這樣就避免了因為定時器開啟而使程序崩潰
C. android用timer做定時任務,崩潰的原因
在做定時任務的時候,有的同學可能能會用到Timer這個定時任務的輔助類,
但是使用它會有潛在的風險,風險如下,
(1)時間計算不準確問題
因為Timer是以絕對時間計算定時任務的,會受到系統時間的影響,如果在任務執行期間,更改了系統時間,那麼會
導致時間計算不準確問題,導致任務沒用按找預定的時間執行。
(2)只能單任務執行
簡單講就是,只能一次執行一個任務,如果前一個任務沒有執行完成,後一個任務是無法並行執行的,只能等待前一個任務執行完成
才能執行。也有可能會出現這樣的結果,前一個任務執行的時間太長,後幾個任務時間短,可能在一個時間段內執行了多個任務,任務又
沒有按照我們要執行的時間執行。
(3)非檢查異常導致非同步任務終止
Timer當在執行的過程中遇到非檢查異常的時候,會導致本次任務失敗,並且接下來的任務也無法被執行,Timer將會終止執行,這不是
我們要的結果,我們需要一套恢復機制。
Java5以後可以用下面的這個類來替代Time,並且解決了以上三個問題
java.util.concurrent.ScheledThreadPoolExecutor
那麼在Android上呢,可以用 java.util.concurrent.ScheledThreadPoolExecutor,也可以用Handler機製做,
但是不建議使用Timer
D. android 怎麼在button上添加倒計時
最簡單的兩種方法吧
開啟一個定時器 (timer 、 countDownTimer) 然後每隔1s 通過handler 讓button 裡面的文字改變一下 就是倒計時了
基本跟第一個相同。自定義一個類 繼承button 然後 裡面寫定時器 settext()
E. Android將倒計時做到極致
在開發倒計時功能時往往我們會為了方便直接使用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不同,這里如果跳了多少秒,就會返回多少次回調。