後臺應用不應做Android待機電池殺手

Android是一個相當開放的平臺,允許我們開發常駐後臺運行的應用程序,依靠TCP長連接接受服務器的消息推送,但也因此在電量消耗方面廣遭詬病。如果開發者,特別是類IM應用的開發者自己還不去了解Android底層的機制,沒準搞出來的應用就變成待機電池殺手了。

Android手機有兩個處理器,一個叫Application Processor(AP),一個叫Baseband Processor(BP)。AP是ARM架構的處理器,用於運行Linux+Android系統;BP用於運行實時操作系統(RTOS),通訊協議棧運行於BP的RTOS之上。非通話時間,BP的能耗基本上在5mA左右,而AP只要處於非休眠狀態,能耗至少在50mA以上,執行圖形運算時會更高。另外LCD工作時功耗在100mA左右,WIFI也在100mA左右。一般手機待機時,AP、LCD、WIFI均進入休眠狀態,這時Android中應用程序的代碼也會停止執行。

Android爲了確保應用程序中關鍵代碼的正確執行,提供了Wake Lock的API,使得應用程序有權限通過代碼阻止AP進入休眠狀態(iOS、WP7都沒這種東西)。如果不領會Android設計者的意圖而濫用Wake Lock API,爲了自身程序在後臺的正常工作而長時間阻止AP進入休眠狀態,後果就相當嚴重了。

首先,完全沒必要擔心AP休眠會導致收不到消息推送。通訊協議棧運行於BP,一旦收到數據包,BP會將AP喚醒,喚醒的時間足夠AP執行代碼完成對收到的數據包的處理過程。其它的如Connectivity事件觸發時AP同樣會被喚醒。那麼唯一的問題就是程序如何執行向服務器發送心跳包的邏輯。你顯然不能靠AP來做心跳計時。Android提供的Alarm Manager就是來解決這個問題的。Alarm運行在BP上,觸發時喚醒AP執行程序代碼。那麼Wake Lock API有啥用呢?比如心跳包從請求到應答,比如斷線重連時驗證密碼這些關鍵邏輯的執行過程,就需要Wake Lock來保護。而一旦一個關鍵邏輯執行成功,應該立即釋放掉Wake Lock了。心跳間隔也不宜過短,至少隔個10分鐘吧。

服務器端也不要有事沒事都向客戶端推送TCP包。客戶端後臺運行時,最好只在必須要客戶端立即在狀態欄顯示內容時推送一個包,別的數據都得緩存起來,等待客戶端進入前臺運行時主動請求,或者也可以加在心跳請求的應答中帶給客戶端。因爲每推送一次,客戶端都得喚醒AP處理這個推送。這個說起來容易,但作爲一個後臺TCP長鏈接的應用,服務端很可能會在一些邏輯的設計上圖省事而抑制不住立即向客戶端推送的衝動。


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