Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android手機的休眠狀態

Android手機的休眠狀態

編輯:關於Android編程

任何一個應用申請了 wakelock 鎖,待機(按:什麼是待機?待機與屏幕黑、鎖屏、休眠的關系是什麼?)時沒有釋放掉,系統是不會進入待機的,直到所有應用的 wakelock 鎖都釋放掉了,才會進入待機。

如果不進行特別的設置,Android會在一定時間後屏幕變暗,在屏幕變暗後一定時間內,CPU也會休眠,大多數的程序都會停止運行,從而節省電量。

Android手機有兩個處理器,一個叫Application Processor(AP),一個叫Baseband Processor(BP)。非通話時間,BP的能耗基本上在5mA左右,而AP只要處於非休眠狀態,能耗至少在50mA以上,執行圖形運算時會更高。一般手機待機時,AP、LCD、WIFI均進入休眠狀態,這時Android中應用程序的代碼也會停止執行。Android為了確保應用程序中關鍵代碼的正確執行,提供了Wake Lock的API,使得APP可以通過之阻止AP進入休眠。但不一定必要,首先,完全沒必要擔心AP休眠會導致收不到消息推送。通訊協議棧運行於BP,一旦收到數據包(按:收到 TCP 數據包才會喚醒 AP,UDP 包不會喚醒),BP會將AP喚醒,喚醒的時間足夠AP執行代碼完成對收到的數據包的處理過程。其它的如Connectivity事件觸發時AP同樣會被喚醒。那麼唯一的問題就是程序如何執行向服務器發送心跳包的邏輯。你顯然不能靠AP來做心跳計時。Android提供的Alarm Manager就是來解決這個問題的。Alarm應該是BP計時(或其它某個帶石英鐘的芯片,不太確定,但絕對不是AP),觸發時喚醒AP執行程序代碼。那麼Wake Lock API有啥用呢?比如心跳包從請求到應答,比如斷線重連重新登陸這些關鍵邏輯的執行過程,就需要Wake Lock來保護(按:只在這些關鍵邏輯時,需要Wake Lock API確保不休眠)。而一旦一個關鍵邏輯執行成功,就應該立即釋放掉Wake Lock了。兩次心跳請求間隔5到10分鐘,基本不會怎麼耗電。除非網絡不穩定,頻繁斷線重連,那種情況辦法不多。

網上有說使用AlarmManager,因為AlarmManager 是Android 系統封裝的用於管理 RTC 的模塊,RTC (Real Time Clock) 是一個獨立的硬件時鐘,可以在 CPU 休眠時正常運行,在預設的時間到達時,通過中斷喚醒 CPU。

休眠有early suspend和suspend,early suspend是可以通過alarm來喚醒的,但是suspend沒法通過alarm來喚醒,進入suspend之後系統自帶的鬧鐘程序都不會起作用了(按:待求證)。

Android 設置–> WLAN –>點擊菜單鍵 選擇 高級 –>休眠狀態下保持WLAN連接的下拉列表{始終、僅限充電時、從不(會增加數據流量)},如果設置不為始終,那麼我們鎖屏休眠後,程序將會處於無網絡狀態,相應的app用戶會一直處於離線模式。

開發中,可以在程序開啟時,讀取Settings.System.WIFI_SLEEP_POLICY值,保存起來,再將其值改為WIFI_SLEEP_POLICY_NEVER使本程序運行期間保持wifi連接,待程序退出時,將原先保存的值還原。

如下表,休眠有多種等級,最高等級的休眠是屏幕、鍵盤、cpu全部休眠:

Flag Value CPU Screen Keyboard PARTIAL_WAKE_LOCK On Off Off SCREEN_DIM_WAKE_LOCK On Dim Off SCREEN_BRIGHT_WAKE_LOCK On Bright Off FULL_WAKE_LOCK On Bright Bright

可以設置不同的模式,讓其產生不同的休眠,比如讓cpu保持運行。
設置代碼如下:

PowerManagerpm =(PowerManager)getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLockwl =pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK,"My Tag");
wl.acquire();
wl.release();
休眠幾個坑點及解決:
1.向服務器輪詢的代碼不執行:曾經做一個應用,利用Timer和TimerTask,來設置對服務器進行定時的輪詢,但是發現機器在某段時間後,輪詢就不再進行了。查了很久才發現是休眠造成的。後來解決的辦法是,利用系統的AlarmManager來執行輪詢。因為雖然系統讓機器休眠,節省電量,但並不是完全的關機,系統有一部分優先級很高的程序還是在執行的,比如鬧鐘,利用AlarmManager可以定時啟動自己的程序,讓cpu啟動,執行完畢再休眠(按:如上述,就是通過 BP 喚醒 AP)。
2.後台長連接斷開:最近遇到的問題。利用Socket長連接實現QQ類似的聊天功能,發現在屏幕熄滅一段時間後,Socket就被斷開。屏幕開啟的時候需進行重連,但每次看Log的時候又發現網絡是鏈接的,後來才發現是cpu休眠導致鏈接被斷開,當你插上數據線看log的時候,網絡cpu恢復,一看網絡確實是鏈接的, 坑。最後使用了PARTIAL_WAKE_LOCK,保持CPU不休眠。
3.調試時是不會休眠的:在調試2的時候,就發現,有時Socket會斷開,有時不會斷開,後來才搞明白,因為我有時是插著數據線進行調試,有時拔掉數據線,這時Android的休眠狀態是不一樣的。而且不同的機器也有不同的表現,比如有的機器,插著數據線就會充電,有的不會,有的機器的設置的充電時屏幕不變暗等等。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved