前言-理論篇
耗電量分析是衡量應(yīng)用性能表現(xiàn)的一個(gè)重要指標(biāo),要做好一款app,不僅僅是實(shí)現(xiàn)功能,我們需要考慮很多性能指標(biāo),讓用戶用的更爽,在開(kāi)發(fā)過(guò)程中,要充分考慮到各項(xiàng)性能指標(biāo),比如定位精度,更高的精度,往往意味著更高的能耗,因此要平衡好精度和功耗,避免我們的app過(guò)多的過(guò)多的電量消耗,而界面卡頓可能意味著大量的多余計(jì)算,不僅影響流暢度,影響電量消耗,網(wǎng)絡(luò)的不合理使用,也會(huì)增加耗電量,這些都是影響耗電量和用戶體驗(yàn)的重要因素,因此必須要重視app耗電量。
1.耗電量概念

-
Idle表示app處于休眠狀態(tài),幾乎不使用電量。 -
Active狀態(tài)說(shuō)明app處于工作狀態(tài),用電量比較高,圖中的第二個(gè)Active的耗電遠(yuǎn)高于第一個(gè),這是因?yàn)閍pp所做的工作類型不同而導(dǎo)致的。 -
Overhead指的是調(diào)起硬件來(lái)支持app功能所消耗的電量,這部分是支持硬件工作必要的電量消耗。 - 圖中橫線以下所包區(qū)域是固定開(kāi)銷(
Fixed Cost),橫線以上區(qū)域是動(dòng)態(tài)開(kāi)銷(Dynamic cost)。
2.節(jié)省電量的四個(gè)基本原則:
識(shí)別:想清楚你需要app在特定時(shí)刻需要完成哪些工作,如果是不必要的工作,考慮延后執(zhí)行或者省去。
優(yōu)化:優(yōu)化app的功能實(shí)現(xiàn),盡可能以更有效率的方式去完成功能。
合并:不需要立刻獲取,可以延后合并執(zhí)行,比如合并網(wǎng)絡(luò)
減少:在滿足需求的基礎(chǔ)上,盡量減少做重復(fù)工作的頻率。
一、耗電大戶

1.網(wǎng)絡(luò)
app進(jìn)行網(wǎng)絡(luò)通信時(shí),蜂窩數(shù)據(jù)和Wi-Fi等元器件開(kāi)始工作就會(huì)消耗大量電能,應(yīng)減少數(shù)據(jù)傳輸,合并網(wǎng)絡(luò)請(qǐng)求,適當(dāng)?shù)木W(wǎng)絡(luò)延時(shí)等。
2.定位
app為了記錄用戶的活動(dòng)或者提供基于位置的服務(wù)會(huì)進(jìn)行定位。定位精度越高,定位時(shí)間越長(zhǎng),消耗電量也就越多。
3.CPU
app做的每件事幾乎都需要用CPU,所以CPU是電能消耗大戶,高CPU使用時(shí)會(huì)迅速消耗掉用戶的電池電量,所以我們要更合理的使用CPU,降低能耗。
4.GPU
app內(nèi)容每次更新到屏幕上都需要消耗電能處理像素信息。動(dòng)畫和視頻格外耗電。不經(jīng)意的或者不必要的內(nèi)容更新同樣會(huì)消耗電能,所以UI不可見(jiàn)時(shí),應(yīng)該避免更新其內(nèi)容。
5.傳感器和藍(lán)牙
長(zhǎng)時(shí)間用不上加速度計(jì)、陀螺儀、磁力計(jì)等設(shè)備的動(dòng)作數(shù)據(jù)時(shí),應(yīng)該停止更新數(shù)據(jù),不然也會(huì)浪費(fèi)電能。應(yīng)按需獲取,用完即停。藍(lán)牙活動(dòng)頻度太高會(huì)消耗電能,應(yīng)該盡量分批、減少數(shù)據(jù)輪詢等操作。
二、測(cè)試工具
1.Energy Impact

1.1Average energy Imapct
Average energy Imapct代表的是app的耗電量評(píng)級(jí),low(綠色區(qū)域)、high (黃色區(qū)域)、very high(紅色區(qū)域)。通過(guò)這張圖,我們可以大致了解 app 電量的使用情況。理想的狀態(tài)是 app 處于 low、high 狀態(tài)。如果處于very high狀態(tài),我們需要分析哪些功能導(dǎo)致耗電量大漲。
1.2Average Componet Utilization
Average Componet Utilization展示的是Overhead、CPU、NetWork、Location、GPU各部分耗電量的占比,通過(guò)這個(gè)占比,我們可以分析各部分耗電量是否較高。
1.3Energy Impact
Energy Impact會(huì)實(shí)時(shí)展示電量消耗,每個(gè)柱子代表每秒的電量消耗,通過(guò)每個(gè)柱子由不同的顏色組成,展示各部分電量消耗的比例,依次是Overhead(紅色)、CPU(藍(lán)色)、網(wǎng)絡(luò)(深黃)、定位(淡黃)、GPU(綠色)、后臺(tái)(深灰)、前臺(tái)(淡灰)、Suspend(白色)。
1.4總結(jié)
在使用Energy Impact的過(guò)程中,首先可以觀察Average energy Imapct。了解app的整體耗電量情況,處在什么位置,對(duì)整體有個(gè)大概的了解,然后通過(guò)Average Componet Utilization來(lái)觀察app整體耗電量中,具體哪一部分占比較高,最后使用Energy Impact進(jìn)行實(shí)時(shí)分析,分析頁(yè)面各部分消耗是否是必要的,比如某個(gè)頁(yè)面只在進(jìn)入的時(shí)候需要獲取經(jīng)緯度,后面不需要實(shí)時(shí)獲取經(jīng)緯度,那么在進(jìn)入頁(yè)面獲取經(jīng)緯度以后,就要將定位關(guān)閉,以減少電量消耗。
優(yōu)點(diǎn):
實(shí)時(shí)性高、數(shù)據(jù)分析可以通過(guò)圖形直觀展示、可以獲取`Overhead(紅色)、CPU(藍(lán)色)、網(wǎng)絡(luò)(深黃)、定位(淡黃)、GPU(綠色)、后臺(tái)(深灰)、前臺(tái)(淡灰)、Suspend(白色)等數(shù)據(jù)和各部分?jǐn)?shù)據(jù)占比。
缺點(diǎn):
顆粒度較大,想做詳細(xì)的分析,需要借助,其它工具。比如針對(duì)CPU的消耗情況,可以通過(guò)Time Profiler來(lái)進(jìn)行分析,分析具體哪部分代碼消耗較多,使用Network Profiler來(lái)分析網(wǎng)絡(luò)的消耗情況、使用Location Profiler來(lái)分析定位的情況,詳細(xì)獲取各部分?jǐn)?shù)據(jù),找到電量的消耗點(diǎn)。
2.Energy Log
2.1Energy Log使用:

設(shè)置路徑:開(kāi)發(fā)者 -> Logging -> Energy -> Start Recording -> Stop Recording。
首先找到開(kāi)發(fā)者,點(diǎn)擊進(jìn)入,找到Logging選項(xiàng),如下圖:
<img src="https://developer.apple.com/library/archive/documentation/Performance/Conceptual/EnergyGuide-iOS/Art/ios_settings_2x.png" width = "300" height = "500" align = center /><img src="https://developer.apple.com/library/archive/documentation/Performance/Conceptual/EnergyGuide-iOS/Art/ios_developer_2x.png" width = "300" height = "500" align = center /></br>
然后點(diǎn)金進(jìn)入Logging選項(xiàng)、進(jìn)入新頁(yè)面,打開(kāi)Energy開(kāi)關(guān),同時(shí)點(diǎn)擊Start Recording,此時(shí)開(kāi)始記錄電量消耗情況,,這時(shí)你可以選擇想要測(cè)試的app,在測(cè)試完畢后,點(diǎn)擊Stop Recording,關(guān)閉電量記錄功能,如下圖:
<img src="https://developer.apple.com/library/archive/documentation/Performance/Conceptual/EnergyGuide-iOS/Art/ios_logging_startrecording_2x.png" width = "300" height = "500" align = center /><img src="https://developer.apple.com/library/archive/documentation/Performance/Conceptual/EnergyGuide-iOS/Art/ios_logging_stoprecording_2x.png" width = "300" height = "500" align = center /></br>
最后,將手機(jī)連接到電腦,導(dǎo)出設(shè)備中的電量記錄數(shù)據(jù),在Energy Log中,可以看到詳細(xì)的電量消耗數(shù)據(jù),如下圖:
<img src="https://developer.apple.com/library/archive/documentation/Performance/Conceptual/EnergyGuide-iOS/Art/instruments_file_menu_importloggeddatafromdevice_menuitem_2x.png" width = "400" height = "500" div align = center /></br>
2.2Energy Log組成:

Energy Usage Log代表能耗消耗級(jí)別,有 0 到 20 的級(jí)別,表示應(yīng)用在任何給定時(shí)間使用了多少電量,值越大表示越耗電。可以用來(lái)分析app的總體能耗。CPU Activity Log代表cpu能源消耗,包括 :Foreground app Activity、Graphics Activity、Media Activity、Other Activity。Network Activity Log代表網(wǎng)絡(luò)能源消耗,包括 :Cellular in、Cellular out、Wi-Fi In、Wi-Fi Out。Display Brightness Log代表屏幕消耗。Sleep/Wake Log代表儀器捕獲有關(guān)設(shè)備當(dāng)前狀態(tài)的信息。Bluetooth On/Off Log代表藍(lán)牙開(kāi)關(guān)狀態(tài)。Wi-Fi On/Off Log代表Wi-Fi開(kāi)關(guān)狀態(tài)。Gps On/Off Log代表Gps開(kāi)關(guān)狀態(tài)。
2.3總結(jié)
在使用Energy Log過(guò)程中,可以通過(guò)橫向比較各個(gè)維度的數(shù)據(jù),來(lái)分析各部分的能源消耗,分析能耗的使用情況,更合理的使用手機(jī)電量。
優(yōu)點(diǎn):
Energy Log可以測(cè)試自己app和別人app的電量消耗,有各個(gè)上面??維度的詳細(xì)數(shù)據(jù),比如:某個(gè)時(shí)刻的cpu使用情況、定位使用情況,可以關(guān)聯(lián)CPU、定位、總能耗消耗等數(shù)據(jù),通過(guò)這些數(shù)據(jù),分析使用是否合理。
缺點(diǎn):
Energy Log只能看整體能耗的水平,同時(shí)由于log不是實(shí)時(shí)的,要具體確定某個(gè)頁(yè)面或者某個(gè)路徑的能耗情況,需要自己測(cè)試的時(shí)候記錄一下,只能大概對(duì)照,而且不能輸出精準(zhǔn)數(shù)據(jù)。
3.Sysdiagnose
Sysdiagnose是用來(lái)診斷系統(tǒng)問(wèn)題的工具,它包括了過(guò)去幾天里,系統(tǒng)整體的詳細(xì)功耗情況、各個(gè)App在各個(gè)硬件上的耗電情況,溫度、電流等等一系列詳細(xì)的數(shù)據(jù)。這些數(shù)據(jù)最終會(huì)存儲(chǔ)在數(shù)據(jù)庫(kù)中,數(shù)據(jù)庫(kù)中包含多張數(shù)據(jù)表,比如在iOS12的系統(tǒng)中,有多達(dá)406張表。
3.1配置和數(shù)據(jù)獲取
蘋果官方在Battery Life Logging Instructions中詳細(xì)說(shuō)明了導(dǎo)出日志的步驟。通過(guò)安裝電量分析的profile來(lái)記錄手機(jī)耗電量信息,使用iTunes進(jìn)行同步,最終從文件夾(~/Library/Logs/CrashReporter/MobileDevice/你的手機(jī)名/)中獲取后綴是.PLSQL或者.PLSQL.gz的幾個(gè)文件,這些文件記錄了手機(jī)中各個(gè)app的耗電情況。
3.2分析數(shù)據(jù)
數(shù)據(jù)庫(kù)中有多張表格,這些表格的具體用途,蘋果沒(méi)有詳細(xì)說(shuō)明,下面是騰訊和一些開(kāi)發(fā)者總結(jié)的部分表格信息。
| 表名 | 內(nèi)容 |
|---|---|
| PLBatteryAgent_EventBackward_Battery | 整機(jī)的電量信息,包含電流、電壓、溫度等信息。(每20秒記錄一條數(shù)據(jù)) |
| PLBatteryAgent_EventBackward_Battery_UI | 剩余電量百分比。(每20秒記錄一條數(shù)據(jù)) |
| PLIOReportAgent_EventBackward_EnergyModel | 整機(jī)不同硬件上的詳細(xì)功耗數(shù)據(jù)。分別記錄了 CPU、GPU、DRAM 等硬件的耗電量。 |
| PLAccountingOperator_Aggregate_RootNodeEnergy | 各個(gè) App 的詳細(xì)耗電數(shù)據(jù)。記錄各個(gè) App 在各個(gè)硬件上的耗電量。(每小時(shí)更新一次數(shù)據(jù)) |
| PLAccountingOperator_EventNone_Nodes | 各個(gè)硬件對(duì)應(yīng)的 Node ID,以及各個(gè) App 的對(duì)應(yīng)的 Node ID。 |
| PLAccountingOperator_EventNone_AllApps | 手機(jī)中安裝的所有 App 的信息 |
| PLApplicationAgent_EventForward_Application | App 運(yùn)行狀態(tài)記錄。記錄各個(gè) App 在某個(gè)時(shí)間段以什么狀態(tài)運(yùn)行。 |
| PLAppTimeService_Aggregate_AppRunTime | App 的運(yùn)行時(shí)長(zhǎng)統(tǒng)計(jì)。(每小時(shí)更新一次數(shù)據(jù)。 |
| PLBatteryAgent_EventForward_LightningConnectorStatus Lighting | 接口連接狀態(tài)。 |
| PLBatteryAgent_EventNone_BatteryConfig | 電池的配置信息。包括電池容量、循環(huán)計(jì)數(shù)、電池壽命、電池溫度等信息。 |
| PLBatteryAgent_EventNone_BatteryShutdown | 電池導(dǎo)致的意外關(guān)機(jī)記錄。 |
| PLCameraAgent_EventForward_Camera | 相機(jī)使用記錄。記錄了相機(jī)類型和使用相機(jī)的 App |
| PLConfigAgent_EventNone_Config | 本機(jī)的一些配置信息和一些系統(tǒng)設(shè)置。 |
| PLDisplayAgent_Aggregate_UserTouch | 屏幕點(diǎn)擊計(jì)數(shù)。每 15 分鐘記錄一條數(shù)據(jù)。 |
| PLDisplayAgent_EventForward_Display | 屏幕亮度信息。包括流明、尼特、亮度滑竿值等信息。 |
| PLProcessNetworkAgent_EventPoint_Connection | 網(wǎng)絡(luò)連接記錄。記錄了發(fā)起網(wǎng)絡(luò)連接的 App、地址、端口等信息。 |
| PLXPCAgent_EventPoint_CacheDelete | 清除緩存的記錄。包括申請(qǐng)的空間大小、清除緩存的耗時(shí)、清除的緩存大小、服務(wù)名稱、緊急程度等信息。 |
我們可以根據(jù)上面的表格,來(lái)分析耗電情況,比如:
- PLBatteryAgent_EventBackward_Battery_UI 可以分析剩余電量曲線
- PLBatteryAgent_EventBackward_Battery 可以分析整體耗電量和溫度變化
- PLAccountingOperator_Aggregate_RootNodeEnergy 和 PLAccountingOperator_EventNone_Nodes 兩張表,可以得到某個(gè) Bundle ID 對(duì)應(yīng)的 App 在各個(gè)硬件上的耗電情況。
下面是一些數(shù)據(jù)獲取的SQL語(yǔ)句:
-
查看APP運(yùn)行的時(shí)間timestamp
select ID,timestamp,datetime(timestamp, 'unixepoch', 'localtime')as time,BundleID from PLAppTimeService_Aggregate_AppRunTime where BundleID='XXX' order by timestamp
-
查看APP的NodeID
select * from PLAccountingOperator_EventNone_Nodes where Name ='XXX'
-
查看APP的電量測(cè)試
select ID,timestamp,datetime(timestamp, 'unixepoch','localtime')as time,Energy,NodeID,RootNodeID from PLAccountingOperator_Aggregate_RootNodeEnergy where NodeID=XXX order by time
-
查看APP某個(gè)時(shí)間點(diǎn)的電量求和
select datetime(timestamp, 'unixepoch', 'localtime')as time,sum(Energy),NodeID from PLAccountingOperator_Aggregate_RootNodeEnergy where NodeID=XXX and timestamp='XXX'
RootNodeID硬件對(duì)照表
| RootNodeID | 硬件 |
|---|---|
| 2 | CPU |
| 4 | VENC |
| 5 | VDEC |
| 6 | ISP |
| 7 | RestOfSOC |
| 8 | GPU |
| 9 | DRAM |
| 10 | Display |
| 11 | WiFi-Data |
| 14 | AudioHeadset |
| 15 | AudioSpeaker |
| 17 | FrontCamera |
| 18 | BackCamera |
| 19 | Torch |
| 37 | BB |
| 38 | BB-Voice |
| 47 | BB-Pssi |
| 48 | GPS |
| 50 | Bluetooth |
| 53 | WiFi-IdLe |
| 54 | APSOCBaseIOReport |
| 55 | AudioCodec |
3.4總結(jié)
Sysdiagnose是一個(gè)可以詳細(xì)獲取各個(gè)維度數(shù)據(jù)的工具,具體到某個(gè)app、某段時(shí)間、某個(gè)硬件的具體能源消耗,可以使用這個(gè)工具,進(jìn)行app的不同場(chǎng)景的能耗數(shù)據(jù)對(duì)比、競(jìng)品app的能耗數(shù)據(jù)分析和對(duì)比,十分精確。
優(yōu)點(diǎn):
可以精確獲取各個(gè)維度的能耗消耗數(shù)據(jù),包括:isp、apsocbase、 display、wifi data、GPU 、CPU、restofsoc、GPS、DRAM、等詳細(xì)數(shù)據(jù)。通過(guò)這些數(shù)據(jù),可以分析某個(gè)app的某段時(shí)間,各個(gè)維度的能耗數(shù)據(jù),這個(gè)數(shù)據(jù)十分精確。
缺點(diǎn):
數(shù)據(jù)不能實(shí)時(shí)獲取,部分?jǐn)?shù)據(jù)需要等待一個(gè)小時(shí)才能獲取,測(cè)試周期長(zhǎng),數(shù)據(jù)量較大,沒(méi)有官方文檔指導(dǎo),需要自己分析各個(gè)表中的數(shù)據(jù)含義。
三、案例分析
1.對(duì)比分析
使用Sysdiagnose,通過(guò)對(duì)比A頁(yè)面和B頁(yè)面(A和B是兩個(gè)不同app相同業(yè)務(wù)的頁(yè)面),來(lái)分析各自耗電量情況,以及可能的優(yōu)化點(diǎn)。下面數(shù)據(jù)單位是1/1000 mAh
1.1A頁(yè)面和B頁(yè)面
測(cè)試條件:iphone7,iOS12.2,記錄5分鐘電量消耗,滑動(dòng)100次,取三次平均值.
| APP | Display | GPS | WiFi-Data | CPU | RestOfSOC | DRAM | GPU | SUM |
|---|---|---|---|---|---|---|---|---|
| A頁(yè)面 | 31888 | 0 | 1753 | 18523 | 5437 | 5059 | 0 | 62660 |
| B頁(yè)面 | 36180 | 9652 | 1500 | 16338 | 4792 | 4460 | 289 | 73211 |

對(duì)比A頁(yè)面和B頁(yè)面能耗數(shù)據(jù),整體能耗數(shù)據(jù),B頁(yè)面高于A頁(yè)面電量消耗,CPU、RestOfSOC、DRAM數(shù)據(jù),A頁(yè)面都高于B頁(yè)面,B頁(yè)面GPS電量消耗量較高,這是因?yàn)锽頁(yè)面一直開(kāi)啟了GPS,Display數(shù)據(jù)B頁(yè)面高于A頁(yè)面,可能和動(dòng)畫使用有關(guān)。通過(guò)這些指標(biāo)分析,可對(duì)比競(jìng)品之間的能耗水平,也可以初步為電量?jī)?yōu)化提供方向。
1.2頁(yè)面中硬件電量消耗

通過(guò)圖片可以看出頁(yè)面中,Display和CPU是主要消耗,占用頁(yè)面整體電量消耗的80%左右,這一部分也是優(yōu)化的重點(diǎn),對(duì)于Diaplay的電量消耗受很多因素影響,比較復(fù)雜,比如:屏幕亮度和動(dòng)畫等影響。
總結(jié):通過(guò)對(duì)比分析,可以獲取app的具體電量消耗水平,可以根據(jù)具體數(shù)據(jù),推斷出app能運(yùn)行的時(shí)間,同時(shí)可以對(duì)比競(jìng)品,判斷app的電量消耗水平,并從具體指標(biāo)分析,初步推斷優(yōu)化方向。
2.需求分析

上面是使用Energy Log來(lái)測(cè)試C頁(yè)面的電量消耗情況,紅色部分是Overhead,表示調(diào)起硬件的正常電量消耗,其占據(jù)頁(yè)面57.1%,網(wǎng)絡(luò)占10.2%,cpu占1.2%,Location占31.1%,但在這個(gè)頁(yè)面中,GPS是一直開(kāi)啟的,也就是圖中的黃色部分,實(shí)際情況是是不需要一直開(kāi)啟GPS定位,這一部分存在優(yōu)化空間,按需要開(kāi)啟和關(guān)閉GPS開(kāi)關(guān)。
總結(jié)
在進(jìn)行電量消耗測(cè)試時(shí),需要對(duì)頁(yè)面需求進(jìn)行具體分析,用來(lái)判別頁(yè)面中網(wǎng)絡(luò)、CPU、GPU、GPS各部分的電量消耗是否是合理和必要的,上面例子的情況,GPS沒(méi)必要一直開(kāi)啟,可以在不需要使用時(shí)關(guān)閉,存在優(yōu)化空間。關(guān)于更多電量?jī)?yōu)化建議,可以參考蘋果官方Apple Energy Guide或者這篇翻譯App功耗優(yōu)化建議,會(huì)從網(wǎng)絡(luò)、CPU、GPU、GPS等方面,更詳細(xì)的角度來(lái)分析耗電量?jī)?yōu)化。
四、優(yōu)化建議
1.網(wǎng)絡(luò)
只要app執(zhí)行網(wǎng)絡(luò)操作,就會(huì)產(chǎn)生大量的見(jiàn)解能耗,網(wǎng)絡(luò)硬件為了響應(yīng)下一次任務(wù),往往會(huì)持續(xù)活躍一段時(shí)間,下面是多次網(wǎng)絡(luò)的能耗圖。

1.1 縮減網(wǎng)絡(luò)請(qǐng)求
減少、壓縮網(wǎng)絡(luò)數(shù)據(jù)??梢越档蜕蟼骰蛳螺d的多媒體內(nèi)容質(zhì)量和尺寸等。
使用緩存,不要重復(fù)下載相同的數(shù)據(jù)。
使用斷點(diǎn)續(xù)傳,否則網(wǎng)絡(luò)不穩(wěn)定時(shí)可能多次傳輸相同的內(nèi)容。
網(wǎng)絡(luò)不可用時(shí)不要嘗試執(zhí)行網(wǎng)絡(luò)請(qǐng)求,盡量只在Wi-Fi情況下聯(lián)網(wǎng)。
讓用戶可以取消長(zhǎng)時(shí)間運(yùn)行或者速度很慢的網(wǎng)絡(luò)操作,設(shè)置合適的超時(shí)時(shí)間。
網(wǎng)絡(luò)請(qǐng)求失敗后用SCNetworkReachability的通知監(jiān)測(cè)網(wǎng)絡(luò)狀態(tài),網(wǎng)絡(luò)可用后再重試。
1.2 延遲聯(lián)網(wǎng)
分批傳輸。比如,下載視頻流時(shí),不要傳輸很小的數(shù)據(jù)包,直接下載整個(gè)文件或者一大塊一大塊地下載。如果提供廣告,一次性多下載一些,然后再慢慢展示。如果要從服務(wù)器下載電子郵件,一次下載多條,不要一條一條地下載。
網(wǎng)絡(luò)操作能推遲就推遲。如果通過(guò)HTTP上傳、下載數(shù)據(jù),建議使用NSURLSession中的后臺(tái)會(huì)話,這樣系統(tǒng)可以針對(duì)整個(gè)設(shè)備所有的網(wǎng)絡(luò)操作優(yōu)化功耗。將可以推遲的操作盡量推遲到設(shè)備充電狀態(tài)并且連接Wi-Fi時(shí)進(jìn)行,比如同步和備份工作。
2.定位
如果你的app只是需要快速確定一下用戶的位置,最好用CLLocationManager的requestLocation (iOS9引入)方法。定位完成之后會(huì)自動(dòng)讓硬件斷電。
除非是在導(dǎo)航的時(shí)候,app大部分時(shí)間不需要實(shí)時(shí)更新,降低位置的更新頻率。
盡量降低定位精度。iOS設(shè)備默認(rèn)采用最高精度定位,如果你的app不是確實(shí)需要米級(jí)的位置信息,不要用最高精度(kCLLocationAccuracyBest)或10米左右的精度(kCLLocationAccuracyNearestTenMeters)。一般來(lái)說(shuō)Core Location提供的精度比你設(shè)置的要好,比如你設(shè)置為3公里左右的精度,可能會(huì)收到100米左右的精度信息。
如果定位精度一直達(dá)不到設(shè)置的精度時(shí),停止更新位置,稍后再試。
需要后臺(tái)更新位置時(shí),盡量把pausesLocationUpdatesAutomatically設(shè)為YES,如果用戶不太可能移動(dòng)的時(shí)候系統(tǒng)會(huì)自動(dòng)暫停位置更新。
后臺(tái)定位時(shí)延時(shí)更新位置。如果要做一個(gè)健身類的軟件追蹤用戶徒步的距離,可以等用戶移動(dòng)一段距離或者過(guò)一段時(shí)間之后再更新位置,這樣可以讓系統(tǒng)優(yōu)化能耗。
3.CPU
3.1盡量減少計(jì)時(shí)器使用
使用計(jì)時(shí)器時(shí),設(shè)置一個(gè)合適的超時(shí)時(shí),不再需要時(shí)及時(shí)關(guān)閉重復(fù)性定時(shí)器。用事件通知代替定時(shí)器。有些app用定時(shí)器監(jiān)控文件內(nèi)容、網(wǎng)絡(luò)或者其他狀態(tài)的變化,這會(huì)導(dǎo)致CPU無(wú)法進(jìn)入閑置狀態(tài)而增加功耗。
3.2減少后臺(tái)工作
實(shí)現(xiàn)UIApplicationDelegate中的方法,應(yīng)用進(jìn)入后臺(tái)前做好暫停任務(wù),保存數(shù)據(jù)等工作。如果確實(shí)需要完成用戶執(zhí)行的一些任務(wù),應(yīng)該調(diào)用UIApplicationDelegate中的beginBackgroundTaskWithExpirationHandler: 方法,這樣后臺(tái)任務(wù)可以繼續(xù)執(zhí)行幾分鐘。任務(wù)執(zhí)行完畢后一定要調(diào)用endBackgroundTask:方法,不要等著系統(tǒng)強(qiáng)行掛起進(jìn)程。
3.3用QoS分級(jí)有序工作
多個(gè)app和眾多操作需要共享CPU、緩存、網(wǎng)絡(luò)等資源,為了保持高效,系統(tǒng)需要根據(jù)不同任務(wù)的優(yōu)先級(jí)智能地管理這些工作。比如更新UI這種重要的事需要多分配資源,而一些后臺(tái)任務(wù)可以延遲一些執(zhí)行。服務(wù)質(zhì)量(quality of service, 以下簡(jiǎn)稱QoS, iOS8引入)級(jí)別可以通過(guò)NSOperation, NSOperationQueue, NSThread objects, dispatch queues, 和pthreads (POSIX threads)指定工作的優(yōu)先級(jí)。
3.4優(yōu)化I/O訪問(wèn)
app每次執(zhí)行I/O任務(wù),比如寫文件,會(huì)導(dǎo)致系統(tǒng)退出閑置模式。而且寫入緩存格外耗電。通過(guò)下列方法可以提高能效、改善app性能。
減小寫入數(shù)據(jù)。數(shù)據(jù)有變化再寫文件,盡量把多個(gè)更改攢到一起一次性寫入。如果只有幾個(gè)字節(jié)的數(shù)據(jù)改變,不要把整個(gè)文件重新寫入一次。如果你的app經(jīng)常要修改大文件里很少的內(nèi)容,可以考慮用數(shù)據(jù)庫(kù)存儲(chǔ)這些數(shù)據(jù)。
避免訪問(wèn)存儲(chǔ)頻度太高。如果app要存儲(chǔ)狀態(tài)信息,要等到狀態(tài)信息有變化時(shí)再寫入。盡量分批修改,不要頻繁地寫入這些小變動(dòng)。
盡量順序讀寫數(shù)據(jù)。在文件中跳轉(zhuǎn)位置會(huì)消耗一些時(shí)間。
盡量從文件讀寫大數(shù)據(jù)塊,一次讀取太多數(shù)據(jù)可能會(huì)引發(fā)一些問(wèn)題。比如,讀取一個(gè)32M文件的全部?jī)?nèi)容可能會(huì)在讀取完成前觸發(fā)內(nèi)容分頁(yè)。
讀寫大量重要數(shù)據(jù)時(shí),考慮用dispatch_io,其提供了基于GCD的異步操作文件I/O的API。用dispatch_io系統(tǒng)會(huì)優(yōu)化磁盤訪問(wèn)。
如果你的數(shù)據(jù)由隨機(jī)訪問(wèn)的結(jié)構(gòu)化內(nèi)容組成,建議將其存儲(chǔ)在數(shù)據(jù)庫(kù)中,可以使用SQLite或Core Data訪問(wèn)。特別是需要操作的內(nèi)容可能增長(zhǎng)到超過(guò)幾兆的時(shí)候。
了解系統(tǒng)如何緩存文件、如何優(yōu)化緩存的使用。如果你不打算多次引用某些數(shù)據(jù),不要自己緩存數(shù)據(jù)。
4.GPU
減少app使用的視圖數(shù)量。
少用運(yùn)算獲得圓角,不論view.maskToBounds還是layer.clipToBounds都會(huì)有很大的資源開(kāi)銷.
盡量少用透明或半透明,會(huì)產(chǎn)生額外的運(yùn)算.
執(zhí)行動(dòng)畫時(shí)不要修改幀率。比如,你的app幀率是60fps,整個(gè)動(dòng)畫就保持這個(gè)幀率不要變。
視頻播放時(shí),app盡量不要在全屏視頻上添加額外的圖層(即使是隱藏的圖層)
5.優(yōu)化通知
盡量用本地通知(local notification),如果你的app不依賴外部數(shù)據(jù),而是需要基于時(shí)間的通知,應(yīng)該用本地通知,可以讓設(shè)備的網(wǎng)絡(luò)硬件休息一下。
遠(yuǎn)程推送有兩個(gè)級(jí)別,一個(gè)是立即推送,另一個(gè)是針對(duì)功耗優(yōu)化過(guò)的延時(shí)推送。如果不是真的需要即時(shí)推送,盡量使用延時(shí)推送。
五、總結(jié)
耗電量分析是應(yīng)用開(kāi)發(fā)中很難的課題,也是衡量性能的重要指標(biāo),做好電量?jī)?yōu)化,可以大幅度提升用戶體驗(yàn),在實(shí)際開(kāi)發(fā)過(guò)程中,電量消耗往往是一個(gè)綜合的結(jié)果,小到日常的代碼習(xí)慣,積少成多,大到網(wǎng)絡(luò)的亂用、不合理的網(wǎng)絡(luò)超時(shí)、不合理的定位使用、不合理的CPU使用,都會(huì)帶來(lái)能耗的過(guò)多消耗,而這些問(wèn)題僅僅會(huì)影響電量,還會(huì)影響用戶體驗(yàn),而對(duì)于這一個(gè)很多因素綜合起來(lái)的結(jié)果,我們需要提高日常開(kāi)發(fā)的代碼質(zhì)量,了解不同實(shí)現(xiàn)方式的差異點(diǎn),優(yōu)化頁(yè)面卡頓,優(yōu)化網(wǎng)絡(luò)使用,優(yōu)化GPS使用等等,只有綜合這些因素,最終獲得較好的用戶體驗(yàn)。
在做耗電量分析的時(shí)候,首先要清楚耗電量較大的點(diǎn),比如:網(wǎng)絡(luò)、定位、CPU、GPU,從這些點(diǎn)來(lái)入手分析,再詳細(xì)分析每個(gè)點(diǎn),細(xì)分每個(gè)點(diǎn)中的一些細(xì)節(jié)的影響,比如:網(wǎng)絡(luò)中可能會(huì)存在導(dǎo)致耗電量過(guò)高的因素,我們可以使用哪些優(yōu)化方法,同時(shí)根據(jù)我們的需求特點(diǎn),怎么來(lái)優(yōu)化,最終找到可優(yōu)化點(diǎn)的,找到解決方案,來(lái)優(yōu)化耗電量。
在優(yōu)化點(diǎn)尋找的過(guò)程中,我們首先可以使用Energy Impact來(lái)實(shí)時(shí)分析,各個(gè)維度指標(biāo)是否有問(wèn)題,占比是否合理,然后在通過(guò)Time Profiler、Network Profiler、Location Profiler等工具對(duì)各項(xiàng)指標(biāo)進(jìn)行詳細(xì)分析,尋找優(yōu)化點(diǎn)。
其次我們可以使用Energy Log來(lái)橫向?qū)Ρ雀鱾€(gè)維度的數(shù)據(jù),來(lái)分析各個(gè)維度對(duì)總功耗的影響,比如:wifi數(shù)據(jù)傳輸和4G數(shù)據(jù)傳輸時(shí),耗電量的對(duì)比,打開(kāi)藍(lán)牙和未打開(kāi)藍(lán)牙,能耗數(shù)據(jù)的對(duì)比,查看各個(gè)維度對(duì)能耗消耗影響的權(quán)重。然后,我們可以使用Sysdiagnose可以進(jìn)行不同場(chǎng)景、競(jìng)品app的對(duì)比分析,查找app的可優(yōu)化點(diǎn),也可以進(jìn)行各種能耗數(shù)據(jù)的對(duì)比分析,以及優(yōu)化前后的能耗數(shù)據(jù)對(duì)比,獲取最終的優(yōu)化效果。Sysdiagnose中的數(shù)量比較精確,同時(shí)數(shù)據(jù)比較全面,可以挖掘更多的信息,來(lái)輔助我們進(jìn)行電量?jī)?yōu)化。</br>
附:iPhone各代電池容量
| ??手機(jī)型號(hào) | ??電池容量 |
|---|---|
| iPhone 11 Pro Max | 3500mAh |
| iPhone 11 Pro | 3190mAh |
| iPhone 11 | 3110mAh |
| iPhone XS Max | 3174mAh |
| iPhone XS | 2658mAh |
| iPhone XR | 2942mAh |
| iPhone 8 Plus | 2675mAh |
| iPhone 8 | 1821mAh |
| iPhone 7 Plus | 2900mAh |
| iPhone 7 | 1960mAh |
| iPhone 6s Plus | 2750mAh |
| iPhone 6s | 1715 mAh |
| iPhone 6 Plus | 2915mAh |
| iPhone 6 | 1810 mAh |
參考內(nèi)容: