前言
在 Android 的開(kāi)發(fā)中我們經(jīng)常需要編寫(xiě)和 時(shí)間 有關(guān)的代碼,比如說(shuō):按鈕的“帕金森”誤觸、驗(yàn)證碼發(fā)送的計(jì)時(shí)器等等姊途;這時(shí)我們可能會(huì)根據(jù) System.currentTimeMillis() 去獲取兩次點(diǎn)擊按鈕的時(shí)間差以及自己編寫(xiě)定時(shí)器 Timmer 和 TimeTask 來(lái)解決上述的問(wèn)題兄一,但是稽物,這其實(shí)都是 Google 不推薦的鞋吉。
CountDownTimer
Android:老子本來(lái)就有倒計(jì)時(shí)器
下面舉一段代碼來(lái)示意——在一個(gè) TextView 中顯示發(fā)送驗(yàn)證碼 10s 的倒計(jì)時(shí)
private TextView vertifyView;
private CountDownTimer timer = new CountDownTimer(10000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
vertifyView.setText((millisUntilFinished / 1000) + "秒后可重發(fā)");
}
@Override
public void onFinish() {
vertifyView.setEnabled(true);
vertifyView.setText("獲取驗(yàn)證碼");
}
};
調(diào)用的時(shí)候很簡(jiǎn)單:timer.start();
最后說(shuō)明一下:CountDownTimer timer = new CountDownTimer(10000, 1000)中,第一個(gè)參數(shù)表示總時(shí)間励烦,第二個(gè)參數(shù)表示間隔時(shí)間谓着。意思就是每隔一秒會(huì)回調(diào)一次方法onTick,然后10秒之后會(huì)回調(diào)onFinish方法坛掠。
SystemClock
別只抓著 System.currentTimeMillis() 不放了
以下詳細(xì)介紹內(nèi)容來(lái)自紅黑聯(lián)盟
1.聲明
public final class SystemClock extends Object 是一個(gè)不可變類(lèi)赊锚。
2.結(jié)構(gòu)
java.lang.Object? android.os.SystemClock
3.概述
它是一個(gè)核心的技術(shù)設(shè)備。三種不同的時(shí)鐘是可用的屉栓,他們不應(yīng)該混淆:
- System.currentTimeMillis()是一個(gè)標(biāo)準(zhǔn)的“墻”時(shí)鐘(時(shí)間和日期)舷蒲,表示從紀(jì)元到現(xiàn)在的毫秒數(shù)。該墻時(shí)鐘能夠被用戶或電話網(wǎng)絡(luò)(見(jiàn)setCurrentTimeMillis(long))設(shè)置友多,所以該時(shí)間可能會(huì)向前或向后不可預(yù)知地跳越牲平。該時(shí)鐘應(yīng)該僅僅被使用在當(dāng)現(xiàn)實(shí)世界的對(duì)應(yīng)的日期和時(shí)間是重要的情況,例如一個(gè)日歷或鬧鐘應(yīng)用程序域滥。而間隔時(shí)間和經(jīng)過(guò)時(shí)間應(yīng)該使用不同的時(shí)鐘纵柿。如果你使用System.currentTimeMillis(),可以考慮監(jiān)聽(tīng)ACTION為ACTION_TIME_TICK启绰、ACTION_TIME_CHANGED昂儒、ACTION_TIMEZONE_CHANGED 的廣播去監(jiān)聽(tīng)時(shí)間變化。
- uptimeMillis()表示自系統(tǒng)啟動(dòng)時(shí)開(kāi)始計(jì)數(shù)委可,以毫秒為單位渊跋。返回的是從系統(tǒng)啟動(dòng)到現(xiàn)在這個(gè)過(guò)程中的處于非休眠期的時(shí)間。當(dāng)系統(tǒng)進(jìn)入深度睡眠時(shí)(CPU關(guān)閉着倾,設(shè)備變黑拾酝,等待外部輸入裝置)該時(shí)鐘會(huì)停止。但是該時(shí)鐘不會(huì)被時(shí)鐘調(diào)整屈呕,閑置或其他節(jié)能機(jī)所影響微宝。這是大多數(shù)間隔時(shí)間的基本點(diǎn),例如Thread.sleep(millls)虎眨、Object.wait(millis)和System.nanoTime()蟋软。該時(shí)鐘被保證是單調(diào)的镶摘,適用于檢測(cè)不包含休眠的間隔時(shí)間的情況。大多數(shù)的方法接受一個(gè)時(shí)間戳的值除了uptimeMillis()時(shí)鐘岳守。
- elapsedRealtime() and elapsedRealtimeNanos() 返回系統(tǒng)啟動(dòng)到現(xiàn)在的時(shí)間凄敢,包含設(shè)備深度休眠的時(shí)間。該時(shí)鐘被保證是單調(diào)的湿痢,即使CPU在省電模式下涝缝,該時(shí)間也會(huì)繼續(xù)計(jì)時(shí)。該時(shí)鐘可以被使用在當(dāng)測(cè)量時(shí)間間隔可能跨越系統(tǒng)睡眠的時(shí)間段譬重。
有幾種機(jī)制控制事件發(fā)生的時(shí)間:
- 標(biāo)準(zhǔn)的方法像Thread.sleep(millis) 和 Object.wait(millis)總是可用的拒逮,這些方法使用的是uptimeMillis()時(shí)鐘,如果設(shè)備進(jìn)入深度休眠臀规,剩余的時(shí)間將被推遲直到系統(tǒng)喚醒滩援。這些同步方法可能被Thread.interrupt()中斷,并且你必須處理InterruptedException異常塔嬉。
- SystemClock.sleep(millis)是一個(gè)類(lèi)似于Thread.sleep(millis)的實(shí)用方法玩徊,但是它忽略InterruptedException異常。使用該函數(shù)產(chǎn)生的延遲如果你不使用Thread.interrupt()谨究,因?yàn)樗鼤?huì)保存線程的中斷狀態(tài)恩袱。
- Handler可以在一個(gè)相對(duì)或者絕對(duì)的時(shí)間設(shè)置異步回調(diào),Handler類(lèi)對(duì)象也使用uptimeMillis()時(shí)鐘胶哲,而且需要一個(gè)loop(經(jīng)常出現(xiàn)在GUI程序中)畔塔。
- AlarmManager可以觸發(fā)一次或重復(fù)事件,即使設(shè)備深度休眠或者應(yīng)用程序沒(méi)有運(yùn)行纪吮。事件可以選擇用 currentTimeMillis或者elapsedRealtime()(ELAPSED_REALTIME)來(lái)設(shè)置時(shí)間俩檬,當(dāng)事件發(fā)生會(huì)觸發(fā)一個(gè)廣播。
4.方法
- public static long currentThreadTimeMillis () 返在當(dāng)前線程運(yùn)行的毫秒數(shù)碾盟。
- public static long elapsedRealtime () 返回系統(tǒng)啟動(dòng)到現(xiàn)在的毫秒數(shù)棚辽,包含休眠時(shí)間。
- public static long elapsedRealtimeNanos () 返回系統(tǒng)啟動(dòng)到現(xiàn)在的納秒數(shù)冰肴,包含休眠時(shí)間屈藐。
- public static boolean setCurrentTimeMillis (long millis) 設(shè)置當(dāng)前的"墻"時(shí)間,要求調(diào)用進(jìn)程有許可權(quán)限熙尉。返回是否成功联逻。
- public static void sleep (long ms) 等待給定的時(shí)間。和Thread.sleep(millis)類(lèi)似检痰,但是它不會(huì)拋出InterruptedException異常包归。事件被推遲到下一個(gè)中斷操作。該方法直到指定的時(shí)間過(guò)去才返回铅歼。
- public static long uptimeMillis () 返回系統(tǒng)啟動(dòng)到現(xiàn)在的毫秒數(shù)公壤,不包含休眠時(shí)間换可。就是說(shuō)統(tǒng)計(jì)系統(tǒng)啟動(dòng)到現(xiàn)在的非休眠期時(shí)間。