Android服務開發(fā)---要優(yōu)雅地活著
文章分類:公司動態(tài) 發(fā)布時間:2014-12-10 原文作者:tbkj 閱讀( )
襄陽太寶科技有限公司提供全程品牌服務的移動應用軟件,專注于IOS(iphone,ipad)、android(安卓)軟件開發(fā)、html5開發(fā)、微信定制開發(fā),我們有頂尖的開發(fā)團隊,富有創(chuàng)意的設計及標準流程化的操作,我們堅持站在客戶的角度為客戶設計方案,帶來高品質(zhì)的服務!
大多數(shù)的Android應用開發(fā)都會將注意力集中在界面功能上,只有少數(shù)應用會需要一個Service,尤其是一個長期運行的Service,去進行后臺聯(lián)網(wǎng)、環(huán)境檢測、媒體播放等功能。Android環(huán)境下的Service有其自身的特點,為了讓服務完美地實現(xiàn)預想的功能,首先要解決的一個重要問題就是:如何讓你的服務優(yōu)雅地活著。
具體來說,就是要做到兩點:
1. 盡可能運行
2. 盡可能省電
看似尋常的道理,實現(xiàn)起來還真不容易,下面一個個來看:
盡可能運行
Android系統(tǒng)會根據(jù)當前資源狀況(主要是內(nèi)存空閑的情況)對后臺服務進行不定期的清理,尤其是當內(nèi)存高度緊張時,會出現(xiàn)大堆服務交替處于“正在重啟服務”的狀態(tài)。前臺服務可以避免這個問題的發(fā)生,但是前提條件是你需要在通知欄顯示一個置頂?shù)臒o法清除的碩大的通知欄。如果你的應用恰巧是類似墨跡天氣或者360這樣正好需要一直給用戶展示這樣的一個通知欄,那么恭喜你,你可以忽略這個頭痛的進程回收問題;但是對大多數(shù)后臺服務來說,顯示這樣的通知并不合適。你可以嘗試修改服務優(yōu)先級,但是在大多數(shù)手機上并不會有什么本質(zhì)上的變化。
另外一個需要考慮的問題是用戶越來越頻繁的“一鍵清理”操作,無論是系統(tǒng)內(nèi)置的一鍵清理功能,還是通過360、獵豹等提供的一鍵清理,都會增加服務殺死或重啟的幾率。當然,如果你的應用有正當理由請求用戶授予root權限,那么太好了,同樣也可以通過各種你懂的方式確保你的Service正常運行。
最后一個讓你頭疼的問題是休眠,嵌入式系統(tǒng)從來都會被設計成利用CPU提供的低功耗模式最大限度降低整機電流消耗,Android系統(tǒng)也不例外。傳統(tǒng)上Android手機處理器被劃分為AP核和CP核兩部分,AP核負責系統(tǒng)和應用,CP核負責無線網(wǎng)絡相關的功能,有些高端機還可能具備其他的功能核心,此外還有各式各樣的外設,如GPS、傳感器、LCD等。為了最小化電流消耗,當前用不到的功能模塊都會通過芯片管腳直接切斷電流供應或者切換成低功耗模式,其中也包括AP核。AP核一旦處于低功耗模式,通常情況下只能依靠硬件中斷才能重新運行,包括CP核過來的網(wǎng)絡事件、物理按鍵、或者是硬件Timer。因此,你的Service可能在任何時候突然停止運行,這個突然而來的STOP可能出現(xiàn)在你的任何進程中的任何線程中正在執(zhí)行的任何一行代碼,絕對不要假設Android系統(tǒng)會禮貌地等你執(zhí)行完任何一個函數(shù)!
所以首先Service需要在架構上設計成可以應付隨時重啟,不要相信隨時都能從緩存中獲取到你想要的一切,定時器也經(jīng)常無法按照你預想的正常工作,數(shù)據(jù)持久化方案需要花費更多的精力進行設計。另外為了隔離Service對主程序的影響,強烈建議將需要常駐后臺的服務配置成獨立進程,通過AIDL與主進程通訊。最后,務必配合使用電源管理Wakelock和鬧鈴管理AlarmManager來控制避免系統(tǒng)進入休眠狀態(tài)。
盡可能省電
上面說到通過AlarmManager和Wakelock來確保Service的正常運行,然而頻繁地喚醒系統(tǒng)以及用Wakelock鎖定CPU就像是喝酒,適時適量有益身心健康,過度沉迷就會危及生命。一旦管理出問題,手機耗電量就會直線上升。目前多數(shù)手機廠商都是使用平均電流來評估應用的耗電量,即計算一定時間內(nèi)未安裝應用和安裝應用情況下整機平均電流,兩值相減即為應用的平均電流。通常Android手機待機狀態(tài)下平均電流在8mA左右,如果你希望你的應用內(nèi)置到某款手機上,對不起,手機廠商對于耗電問題絕不手軟,高于5mA平均電流消耗的應用通常是無法被接受的。如下圖那樣如果長時間工作導致持續(xù)高電流,會成倍增加應用的平均電流值。
為了更好地在耗電方面進行優(yōu)化,首先需要了解到每喚醒一次AP核,都會帶來一段時間的固定開銷(可能是幾百ms),然后再重新休眠,即使你什么也不做。其次,喚醒后的耗電,一般只與工作時長有關,與工作強度關系不大,就我目前所知大多數(shù)ARM芯片還沒有類似Intel芯片那種調(diào)頻功能。
此外,負責網(wǎng)絡處理的CP核的開啟需要非常小心,因為CP核是耗電大戶,而且為了提高網(wǎng)絡通訊效率,CP核開啟后會保持比AP核更長的工作時間,根據(jù)手機和網(wǎng)絡類型的不同,可能是1到5s甚至是更長時間。最后,也是最好理解的,每開啟一個外設,都會額外增加耗電。
所以,優(yōu)化的措施主要就是盡可能減少喚醒的頻率,以及進行任務合并,尤其是網(wǎng)絡相關的操作,盡量合并到同一時間內(nèi)處理。在文件IO(尤其是網(wǎng)絡IO)期間,AP核如果無所事事,就盡量不要占用Wakelock,釋放出來。當有網(wǎng)絡事件需要處理時,CP負責喚醒AP,進行后續(xù)操作。要實現(xiàn)這點很不容易,根據(jù)業(yè)務需求,程序結(jié)構上需要做很細致的規(guī)劃。最后就是,盡量別碰其他的外設。
結(jié)束語
沒有一個應用希望自己長期占據(jù)軟件耗電排行榜首,如果應用不再前臺運行的時候也想做點有意義的事,就需要非常謹慎。如果每個應用都不顧他人的感受在手機上盡情撒野,那么總會有人站出來把這樣的熊孩子揪出來干掉的。資源是大家的,請珍惜每1mAh的電。
下面來看一下國內(nèi)專業(yè)推送服務商 “個推”是怎么做的,作為專注推送三周年領先者,個推的做法是:
1. 開啟流量合并通道。目前,大多第三方信息推送采用的方式是,為應用開發(fā)者提供SDK包嵌入應用程序來實現(xiàn)信息的推送。于是,每個用戶的手機里可能會有多個應用都包含了個推的SDK,也就是服務通道。這樣,每個SDK在信息推送過程中,都會消耗一小部分的流量。個推可以自動將這樣的多個推送服務通道合并,只開啟一個通道即可。
2. 增量更新下,一般當應用有新版本時,我們都需要下載一個全新的安裝包,個推推送的應用版本更新通知時,只要升級差量部分即可,也起到很好的省電省流量的效果。
大多數(shù)的Android應用開發(fā)都會將注意力集中在界面功能上,只有少數(shù)應用會需要一個Service,尤其是一個長期運行的Service,去進行后臺聯(lián)網(wǎng)、環(huán)境檢測、媒體播放等功能。Android環(huán)境下的Service有其自身的特點,為了讓服務完美地實現(xiàn)預想的功能,首先要解決的一個重要問題就是:如何讓你的服務優(yōu)雅地活著。
具體來說,就是要做到兩點:
1. 盡可能運行
2. 盡可能省電
看似尋常的道理,實現(xiàn)起來還真不容易,下面一個個來看:
盡可能運行
Android系統(tǒng)會根據(jù)當前資源狀況(主要是內(nèi)存空閑的情況)對后臺服務進行不定期的清理,尤其是當內(nèi)存高度緊張時,會出現(xiàn)大堆服務交替處于“正在重啟服務”的狀態(tài)。前臺服務可以避免這個問題的發(fā)生,但是前提條件是你需要在通知欄顯示一個置頂?shù)臒o法清除的碩大的通知欄。如果你的應用恰巧是類似墨跡天氣或者360這樣正好需要一直給用戶展示這樣的一個通知欄,那么恭喜你,你可以忽略這個頭痛的進程回收問題;但是對大多數(shù)后臺服務來說,顯示這樣的通知并不合適。你可以嘗試修改服務優(yōu)先級,但是在大多數(shù)手機上并不會有什么本質(zhì)上的變化。
另外一個需要考慮的問題是用戶越來越頻繁的“一鍵清理”操作,無論是系統(tǒng)內(nèi)置的一鍵清理功能,還是通過360、獵豹等提供的一鍵清理,都會增加服務殺死或重啟的幾率。當然,如果你的應用有正當理由請求用戶授予root權限,那么太好了,同樣也可以通過各種你懂的方式確保你的Service正常運行。
最后一個讓你頭疼的問題是休眠,嵌入式系統(tǒng)從來都會被設計成利用CPU提供的低功耗模式最大限度降低整機電流消耗,Android系統(tǒng)也不例外。傳統(tǒng)上Android手機處理器被劃分為AP核和CP核兩部分,AP核負責系統(tǒng)和應用,CP核負責無線網(wǎng)絡相關的功能,有些高端機還可能具備其他的功能核心,此外還有各式各樣的外設,如GPS、傳感器、LCD等。為了最小化電流消耗,當前用不到的功能模塊都會通過芯片管腳直接切斷電流供應或者切換成低功耗模式,其中也包括AP核。AP核一旦處于低功耗模式,通常情況下只能依靠硬件中斷才能重新運行,包括CP核過來的網(wǎng)絡事件、物理按鍵、或者是硬件Timer。因此,你的Service可能在任何時候突然停止運行,這個突然而來的STOP可能出現(xiàn)在你的任何進程中的任何線程中正在執(zhí)行的任何一行代碼,絕對不要假設Android系統(tǒng)會禮貌地等你執(zhí)行完任何一個函數(shù)!
所以首先Service需要在架構上設計成可以應付隨時重啟,不要相信隨時都能從緩存中獲取到你想要的一切,定時器也經(jīng)常無法按照你預想的正常工作,數(shù)據(jù)持久化方案需要花費更多的精力進行設計。另外為了隔離Service對主程序的影響,強烈建議將需要常駐后臺的服務配置成獨立進程,通過AIDL與主進程通訊。最后,務必配合使用電源管理Wakelock和鬧鈴管理AlarmManager來控制避免系統(tǒng)進入休眠狀態(tài)。
盡可能省電
上面說到通過AlarmManager和Wakelock來確保Service的正常運行,然而頻繁地喚醒系統(tǒng)以及用Wakelock鎖定CPU就像是喝酒,適時適量有益身心健康,過度沉迷就會危及生命。一旦管理出問題,手機耗電量就會直線上升。目前多數(shù)手機廠商都是使用平均電流來評估應用的耗電量,即計算一定時間內(nèi)未安裝應用和安裝應用情況下整機平均電流,兩值相減即為應用的平均電流。通常Android手機待機狀態(tài)下平均電流在8mA左右,如果你希望你的應用內(nèi)置到某款手機上,對不起,手機廠商對于耗電問題絕不手軟,高于5mA平均電流消耗的應用通常是無法被接受的。如下圖那樣如果長時間工作導致持續(xù)高電流,會成倍增加應用的平均電流值。
為了更好地在耗電方面進行優(yōu)化,首先需要了解到每喚醒一次AP核,都會帶來一段時間的固定開銷(可能是幾百ms),然后再重新休眠,即使你什么也不做。其次,喚醒后的耗電,一般只與工作時長有關,與工作強度關系不大,就我目前所知大多數(shù)ARM芯片還沒有類似Intel芯片那種調(diào)頻功能。
此外,負責網(wǎng)絡處理的CP核的開啟需要非常小心,因為CP核是耗電大戶,而且為了提高網(wǎng)絡通訊效率,CP核開啟后會保持比AP核更長的工作時間,根據(jù)手機和網(wǎng)絡類型的不同,可能是1到5s甚至是更長時間。最后,也是最好理解的,每開啟一個外設,都會額外增加耗電。
所以,優(yōu)化的措施主要就是盡可能減少喚醒的頻率,以及進行任務合并,尤其是網(wǎng)絡相關的操作,盡量合并到同一時間內(nèi)處理。在文件IO(尤其是網(wǎng)絡IO)期間,AP核如果無所事事,就盡量不要占用Wakelock,釋放出來。當有網(wǎng)絡事件需要處理時,CP負責喚醒AP,進行后續(xù)操作。要實現(xiàn)這點很不容易,根據(jù)業(yè)務需求,程序結(jié)構上需要做很細致的規(guī)劃。最后就是,盡量別碰其他的外設。
結(jié)束語
沒有一個應用希望自己長期占據(jù)軟件耗電排行榜首,如果應用不再前臺運行的時候也想做點有意義的事,就需要非常謹慎。如果每個應用都不顧他人的感受在手機上盡情撒野,那么總會有人站出來把這樣的熊孩子揪出來干掉的。資源是大家的,請珍惜每1mAh的電。
下面來看一下國內(nèi)專業(yè)推送服務商 “個推”是怎么做的,作為專注推送三周年領先者,個推的做法是:
1. 開啟流量合并通道。目前,大多第三方信息推送采用的方式是,為應用開發(fā)者提供SDK包嵌入應用程序來實現(xiàn)信息的推送。于是,每個用戶的手機里可能會有多個應用都包含了個推的SDK,也就是服務通道。這樣,每個SDK在信息推送過程中,都會消耗一小部分的流量。個推可以自動將這樣的多個推送服務通道合并,只開啟一個通道即可。
2. 增量更新下,一般當應用有新版本時,我們都需要下載一個全新的安裝包,個推推送的應用版本更新通知時,只要升級差量部分即可,也起到很好的省電省流量的效果。
原文來自:tbkj