前言
起因:在路測(cè)階段有不少同學(xué)反映,滿電的手機(jī)出去路測(cè),回來(lái)時(shí)已基本沒(méi)電;也有反饋路測(cè)期間手機(jī)發(fā)燙;
了解原因之前我們先要知道CPU為什么會(huì)耗電?
CPU在運(yùn)行復(fù)雜度不同的任務(wù)是采用調(diào)頻處理的,當(dāng)手機(jī)處理復(fù)雜任務(wù)時(shí),頻率也會(huì)提高,自然對(duì)于電量的需求會(huì)增加。另外,當(dāng)APP進(jìn)程的CPU使用率超過(guò)1%的時(shí)候,都是耗電比較大的。
可能導(dǎo)致App耗電過(guò)快的原因
1、頻繁的交互
正常情況下,關(guān)閉后臺(tái)軟件 VS 行程中導(dǎo)航的時(shí)候手機(jī)耗電一定是差別很大的,行程中涉及司乘同現(xiàn)、路線規(guī)劃、最佳視野、定位上報(bào)...等等
再比如,在玩王者榮耀游戲 VS 聽音樂(lè)的時(shí)候,因?yàn)橥嬗螒虻臅r(shí)候會(huì)和屏幕產(chǎn)生很多的交互,但是聽音樂(lè)就不會(huì)這樣,頻繁的交互式非常耗電的。
2、動(dòng)畫效果
順風(fēng)車場(chǎng)景包含了大量的動(dòng)效場(chǎng)景,例如,首頁(yè)發(fā)單控件下拉動(dòng)效、司乘等待頁(yè)動(dòng)效、行程中動(dòng)效...等等
當(dāng)我們?cè)O(shè)計(jì)交互動(dòng)畫的效果時(shí),調(diào)用的都是view或者其子類,比如按鈕在點(diǎn)擊前是效果1,點(diǎn)擊后變成效果2,設(shè)置更復(fù)雜的動(dòng)畫,此時(shí)view的重繪讓CPU或GPU不斷計(jì)算,耗電量同樣會(huì)增加。
3、布局文件嵌套太多
app的布局文件影響著app展示給用戶的效果,當(dāng)布局過(guò)于復(fù)雜,布局文件嵌套太多時(shí),布局xml文件越來(lái)越繁多,查找、加載這些文件顯示時(shí)會(huì)造成CPU計(jì)算加重,也會(huì)影響手機(jī)耗電。
參考way社區(qū)發(fā)表的一篇文章:順風(fēng)車Android性能優(yōu)化之View布局優(yōu)化 (http://way.xiaojukeji.com/article/10784)
4、頻繁的網(wǎng)絡(luò)請(qǐng)求
5、定時(shí)任務(wù)喚醒CPU
安卓CPU休眠時(shí)一種安卓極致省電的一種模式,如果你息屏一段時(shí)間,CPU會(huì)自動(dòng)進(jìn)入休眠。但在某些場(chǎng)景下,比如當(dāng)訂單狀態(tài)變更時(shí),我們的應(yīng)用會(huì)給你推送通知,當(dāng)你亮屏打開手機(jī)后會(huì)看到這條通知,那么它就是喚醒了手機(jī)的CPU,而我們知道CPU工作時(shí)需要消耗電量,尤其是在頻繁喚醒的情況下,或者發(fā)送心跳包。
6、頻繁切換網(wǎng)絡(luò)
切換網(wǎng)絡(luò)往往需要硬件的支持,硬件需要跑起來(lái)也是需要電量的,并且數(shù)據(jù)網(wǎng)絡(luò)比wifi更加耗電,2G,3G,4G網(wǎng)絡(luò)耗電都不同。
7、高運(yùn)算量代碼
比如解析json這類耗時(shí)時(shí)間較長(zhǎng)的數(shù)據(jù)格式,或二進(jìn)制編碼解碼等。比如,首頁(yè)response返回的json體多則幾百行,json解析效率主要是解析耗時(shí)
8、代碼中執(zhí)行的timer定時(shí)器
Android 的 Timer 類可以用來(lái)計(jì)劃需要循環(huán)執(zhí)行的任務(wù),Timer 的問(wèn)題是它需要用 WakeLock 讓 CPU 保持喚醒狀態(tài),再加上不恰當(dāng)?shù)氖褂肳akeLock最終沒(méi)有合理釋放掉,使得系統(tǒng)長(zhǎng)時(shí)間無(wú)法進(jìn)入休眠,勢(shì)必導(dǎo)致高耗電
timer實(shí)現(xiàn)的源碼是用while(true)循環(huán)來(lái)檢測(cè)是否到時(shí)間點(diǎn),沒(méi)到就wait,并且continue
9、傳感器
安全需求中的全程開端需要App置于前臺(tái)(屏幕保持常亮)、端內(nèi)大部分場(chǎng)景需要GPS請(qǐng)求
10、SD卡讀寫
11、藍(lán)牙
優(yōu)化建議
1、減少應(yīng)用與屏幕的交互
在設(shè)計(jì)app的時(shí)候適當(dāng)簡(jiǎn)化用戶的操作流程,簡(jiǎn)化掉可以幫助用戶做的,不僅僅是為了省電,也可以提高用戶的效率。
2、減少不必要的動(dòng)畫效果
有些復(fù)雜的動(dòng)畫效果完全可以省略,采用靜態(tài)的app啟動(dòng)頁(yè),或者是點(diǎn)擊事件的交互、頁(yè)面跳轉(zhuǎn)時(shí)就用盡量減少不必要的動(dòng)畫效果。
3、簡(jiǎn)化布局文件,避免過(guò)多的嵌套
4、HTTP請(qǐng)求優(yōu)化
http請(qǐng)求可以采用gzip壓縮減少傳輸過(guò)程中的數(shù)據(jù)量,app發(fā)起http請(qǐng)求和服務(wù)端返回的http請(qǐng)求數(shù)據(jù)都采用gzip壓縮
5、json解析
比較流行的有fast jackson,jackson,gson,jackson解析效率相當(dāng)高,基本是gson的十倍
6、讀寫優(yōu)化
盡量減少SD卡讀寫操作,包括SharedPreferences,能保存在內(nèi)存中的盡量保存在內(nèi)存中,不用害怕內(nèi)存爆掉,內(nèi)存絕對(duì)不會(huì)因?yàn)槎啻媪藥资畟€(gè)變量而溢出的,如果需要保存到SD卡的數(shù)據(jù)很多,那只能說(shuō)我們的App在設(shè)計(jì)實(shí)現(xiàn)方面還有問(wèn)題,建議重新理下App的編碼設(shè)計(jì)或者是功能設(shè)計(jì)
7、AlarmManager
通過(guò)AlarmManager可喚醒設(shè)備,但項(xiàng)目中不限制的濫用,也會(huì)導(dǎo)致系統(tǒng)被頻繁喚醒;
8、盡量使用WiFi
testerhome大神說(shuō),因?yàn)槭謾C(jī)數(shù)據(jù)流量會(huì)調(diào)用手機(jī)上面的一些硬件設(shè)備,從而喚醒cpu增加耗電,這個(gè)跟開啟攝像頭,開啟gps是一樣的,一涉及調(diào)用硬件設(shè)備的絕對(duì)喚醒cpu,一喚醒cpu耗電絕對(duì)增加
9、非必要,則不要監(jiān)聽網(wǎng)絡(luò)廣播
10、非必要,則不要使用后臺(tái)常駐service
雖然我們很清楚耗電的原因,但涉及的因素方方面面,我們無(wú)法改變重構(gòu)底層代碼、無(wú)法優(yōu)化整個(gè)系統(tǒng)、技術(shù)瓶頸、不得不定時(shí)發(fā)送心跳包…想做好性能也并非易事。但是我們能夠做到是盡量減少交互、改善產(chǎn)品交互邏輯、優(yōu)化動(dòng)畫效果、簡(jiǎn)化布局…其實(shí)我們能夠做的還很多。
耗電舉例分析
power_profile.xml 功耗配置文件部分配置如下:
<device name="Android">
? <item name="battery.capacity">3450</item>
? ...
? <item name="screen.on">178.708</item>
? <item name="screen.full">240.790</item>
? ...
</device>
這款手機(jī)的電池容量為3450mAh,亮屏?xí)r電流為178.708mA,亮度調(diào)節(jié)到最大時(shí)電流為240.790mA。這意味著,如果排除其他耗電影響,僅僅亮屏,該手機(jī)可以維持3450mAh178.708mA=19.305h(小時(shí));如果將屏幕亮度調(diào)到最大,該手機(jī)可以維持3450mAh240.790mA=14.327h(小時(shí))。因此,電池容量越大,手機(jī)的續(xù)航時(shí)間一般更長(zhǎng);在手機(jī)重度使用的情況下,耗電會(huì)加快。
除了屏幕,手機(jī)上需要供電的模塊還有很多:CPU、相機(jī)、閃光燈、音頻、視頻、藍(lán)牙、modem、wifi、gps。按單位電流值排一個(gè)序的話:
相機(jī)(平均1152mAh) > modem(最高604mAh) > wifi(發(fā)數(shù)據(jù)370mAh) > CPU(最高頻率290mAh) > 屏幕(最亮240mAh) > 音頻(75mAh) > 視頻(50mAh) > GPS(49mAh) > 藍(lán)牙(8mAh)
將電池容量分成100隔的話,每隔電就是34.5mAh,既如果一個(gè)小時(shí)內(nèi)用了34.5mA的電量,那就會(huì)掉一個(gè)隔電。參考這些電流值,可以很容易知道:手機(jī)拍照是很耗電的,使用數(shù)據(jù)流量看視頻也是很耗電的,重度使用情況下,手機(jī)也就能使用2~3個(gè)小時(shí)。但如果手機(jī)一直處于休眠狀態(tài),CPU的單位電流值不到2mAh,這樣待機(jī)個(gè)把月也是可以的。所以,一個(gè)正常的手機(jī),電池是否耐用,是跟個(gè)人的使用習(xí)慣相關(guān)的。
我們平時(shí)分析的功耗問(wèn)題,是在同等條件下的對(duì)比試驗(yàn),找到異常耗電的原因。譬如:手機(jī)的初始條件相似(電池容量、相同的應(yīng)用等),在同樣的環(huán)境下放置一個(gè)晚上,如果對(duì)比機(jī)出現(xiàn)明顯的掉電異常,就可以通過(guò)電量日志找到異常耗電的原因。
參考文獻(xiàn)
官方建議優(yōu)化的一些方法
https://developer.android.google.cn/training/monitoring-device-state/index.html
對(duì)低電耗模式和應(yīng)用待機(jī)模式進(jìn)行針對(duì)性優(yōu)化
https://developer.android.google.cn/training/monitoring-device-state/doze-standby.html
Android 7.0新特性對(duì)電池管理進(jìn)一步加強(qiáng),一些新的變化可能多對(duì)我們現(xiàn)有的業(yè)務(wù)會(huì)造成影響需關(guān)注
https://developer.android.google.cn/about/versions/nougat/android-7.0-changes.html#perf