Android開發之獲取手機運行時間

前言

昨天我碰到一個問題,需要判斷兩次的時間,我當時的第一反應是用System.currentTimeMillis()來判斷,最後發現這樣會有一個BUG,那就是用戶如果手動修改時間,那就全亂套了,於是我想有沒有一個時間是隻增加不減少,並且用戶是不能修改的?一查,發現還真有,主要和SystemClock有關,接下來對這個類進行學習。

SystemClock

三種時鐘都是有效的,它們不應該被混淆:

  1. System.currentTimeMillis()是一個標準的“牆”時鐘(時間和日期),表示從紀元到現在的毫秒數。該牆時鐘能夠被用戶或電話網絡(見setCurrentTimeMillis(long))設置,所以該時間可能會向前或向後不可預知地跳越。該時鐘應該僅僅被使用在當現實世界對應的日期和時間非常重要的情況下,比如日曆或鬧鐘應用程序。而間隔時間和經歷時間的測算應該使用不同的時鐘。如果你使用System.currentTimeMillis(),當時間變化時時可以考慮監聽ACTION爲ACTION_TIME_TICK、ACTION_TIME_CHANGED和ACTION_TIMEZONE_CHANGED的廣播。

  2. uptimeMillis()表示自系統啓動時開始計時,以毫秒爲單位。返回的是從系統啓動到現在這個過程中的處於非休眠期的時間。當系統進入深度睡眠時(CPU關閉,設備變黑,等待外部輸入裝置)該時鐘會停止。但是該時鐘不會被時鐘調整、閒置或其他節能機制所影響。這是大多數間隔時間的基本點,例如Thread.sleep(millls)、Object.wait(millis)和System.nanoTime()。該時鐘被保證是單調的,適用於檢測不包含休眠的間隔時間的情況。大多數接受一個時間戳值的方法認爲是使用了uptimeMillis()時鐘。

  3. elapsedRealtime()elapsedRealtimeNanos() 返回系統啓動到現在的時間,包含設備深度休眠的時間。該時鐘被確保單調,即使CPU在省電模式下,該時間也會繼續計時。該時鐘可以被使用在測量時間間隔時系統可能睡眠的時間段。

這有一些機制爲了控制定時事件的:

  1. 標準的功能Thread.sleep(millis)Object.wait(millis)都總是合適的。這是功能使用uptimeMillis()時鐘;如果該設備進入睡眠,剩餘的時間將被推遲直到系統喚醒。這些同步功能可能被中斷伴隨Thread.interrupt()方法,並且你必須處理InterruptedException異常。

  2. SystemClock.sleep(millis)是一種實用工具函數變化類似於Thread.sleep(millis),但是它忽視了InterruptedException異常。使用該函數產生的延遲如果你不使用Thread.interrupt(),因爲它會保存線程的中斷狀態。

  3. 處理程序類可以安排在絕對或相對時間異步回調。處理器類對象也使用uptimeMillis()時鐘,並且需要一個eventloop(正常呈現在任何一個GUI應用程序上)。該AlarmManager可以觸發一次或重複事件去發生即使在深睡眠或你的應用程序沒有運行。事件可能有計劃的發生伴隨你的currentTimeMillis()(RTC)機會或elapsedRealtime()(ELAPSED_REALTIME),並且引起一個意圖廣播當它們發生時。

有幾種機制可以控制事件發生的時間:

  1. 對標準的方法比如Thread.sleep(millis)Object.wait(millis)都是有效的,這些方法使用的是uptimeMillis()時鐘,如果設備進入深度休眠,剩餘的時間將被推遲直到系統喚醒。這些同步方法可能被Thread.interrupt()中斷,你必須處理InterruptedException異常。

  2. SystemClock.sleep(millis)是一個類似於Thread.sleep(millis)的實用方法,但是它忽略InterruptedException異常(其實就是使用Thread.sleep,不過對異常進行了處理)。使用該函數會產生延遲,如果你不使用Thread.interrupt(),因爲它會保存線程的中斷狀態。

  3. Handler類可以在一個相對或者絕對的時間設置異步回調,Handler對象也使用uptimeMillis()時鐘,而且需要一個loop(經常出現在GUI程序中)。

  4. AlarmManager可以觸發一次或重複事件,即使設備深度休眠或者應用程序沒有運行。事件可以選擇用currentTimeMillis()(RTC)或者elapsedRealtime()(ELAPSED_REALTIME)來設置時間,當事件發生會觸發一個Intent廣播。

  5. 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() 返回系統啓動到現在的毫秒級時間,不包含休眠時間。(系統啓動到現在的非休眠期時間)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章