昨天我碰到一個問題,須要判斷兩次的時間,我當時的第一反應是用System.currentTimeMillis()來判斷,最後發現這樣會有一個BUG,那就是用戶若是手動修改時間,那就全亂套了,因而我想有沒有一個時間是隻增長不減小,而且用戶是不能修改的?一查,發現還真有,主要和SystemClock有關,接下來對這個類進行學習。網絡
三種時鐘都是有效的,它們不該該被混淆:異步
System.currentTimeMillis()是一個標準的「牆」時鐘(時間和日期),表示從紀元到如今的毫秒數。該牆時鐘可以被用戶或電話網絡(見setCurrentTimeMillis(long))設置,因此該時間可能會向前或向後不可預知地跳越。該時鐘應該僅僅被使用在當現實世界對應的日期和時間很是重要的狀況下,好比日曆或鬧鐘應用程序。而間隔時間和經歷時間的測算應該使用不一樣的時鐘。若是你使用System.currentTimeMillis(),當時間變化時時能夠考慮監聽ACTION爲ACTION_TIME_TICK、ACTION_TIME_CHANGED和ACTION_TIMEZONE_CHANGED的廣播。函數
uptimeMillis()表示自系統啓動時開始計時,以毫秒爲單位。返回的是從系統啓動到如今這個過程當中的處於非休眠期的時間。當系統進入深度睡眠時(CPU關閉,設備變黑,等待外部輸入裝置)該時鐘會中止。可是該時鐘不會被時鐘調整、閒置或其餘節能機制所影響。這是大多數間隔時間的基本點,例如Thread.sleep(millls)、Object.wait(millis)和System.nanoTime()。該時鐘被保證是單調的,適用於檢測不包含休眠的間隔時間的狀況。大多數接受一個時間戳值的方法認爲是使用了uptimeMillis()時鐘。工具
elapsedRealtime() 和elapsedRealtimeNanos() 返回系統啓動到如今的時間,包含設備深度休眠的時間。該時鐘被確保單調,即便CPU在省電模式下,該時間也會繼續計時。該時鐘能夠被使用在測量時間間隔時系統可能睡眠的時間段。oop
這有一些機制爲了控制定時事件的:學習
標準的功能Thread.sleep(millis)和Object.wait(millis)都老是合適的。這是功能使用uptimeMillis()時鐘;若是該設備進入睡眠,剩餘的時間將被推遲直到系統喚醒。這些同步功能可能被中斷伴隨Thread.interrupt()方法,而且你必須處理InterruptedException異常。spa
SystemClock.sleep(millis)是一種實用工具函數變化相似於Thread.sleep(millis),可是它忽視了InterruptedException異常。使用該函數產生的延遲若是你不使用Thread.interrupt(),由於它會保存線程的中斷狀態。線程
處理程序類能夠安排在絕對或相對時間異步回調。處理器類對象也使用uptimeMillis()時鐘,而且須要一個eventloop(正常呈如今任何一個GUI應用程序上)。該AlarmManager能夠觸發一次或重複事件去發生即便在深睡眠或你的應用程序沒有運行。事件可能有計劃的發生伴隨你的currentTimeMillis()(RTC)機會或elapsedRealtime()(ELAPSED_REALTIME),而且引發一個意圖廣播當它們發生時。對象
有幾種機制能夠控制事件發生的時間:進程
對標準的方法好比Thread.sleep(millis) 和Object.wait(millis)都是有效的,這些方法使用的是uptimeMillis()時鐘,若是設備進入深度休眠,剩餘的時間將被推遲直到系統喚醒。這些同步方法可能被Thread.interrupt()中斷,你必須處理InterruptedException異常。
SystemClock.sleep(millis)是一個相似於Thread.sleep(millis)的實用方法,可是它忽略InterruptedException異常(其實就是使用Thread.sleep,不過對異常進行了處理)。使用該函數會產生延遲,若是你不使用Thread.interrupt(),由於它會保存線程的中斷狀態。
Handler類能夠在一個相對或者絕對的時間設置異步回調,Handler對象也使用uptimeMillis()時鐘,並且須要一個loop(常常出如今GUI程序中)。
AlarmManager能夠觸發一次或重複事件,即便設備深度休眠或者應用程序沒有運行。事件能夠選擇用currentTimeMillis()(RTC)或者elapsedRealtime()(ELAPSED_REALTIME)來設置時間,當事件發生會觸發一個Intent廣播。
public方法:
static long currentThreadTimeMillis() 返在當前線程運行的毫秒數。
static long elapsedRealtime() 返回系統啓動到如今的毫秒數,包含休眠時間。
static long elapsedRealtimeNanos() 返回系統啓動到如今的納秒數,包含休眠時間。
static boolean setCurrentTimeMillis(long millis) 設置當前掛鐘時間,以毫秒爲單位。須要調用進程具備相應的權限。
static void sleep(long ms) 等待給定的時間(uptimeMillis)。和Thread.sleep(millis)相似,可是它不會拋出InterruptedException異常。事件被推遲到下一個中斷操做。該方法直到指定的時間過去才返回。
static long uptimeMillis() 返回系統啓動到如今的毫秒級時間,不包含休眠時間。(系統啓動到如今的非休眠期時間)