本文由雲+社群發表
作者:騰訊移動品質中心TMQ
1、研究背景:
在2017年Google I/O大會上,Google釋出了Google Play管理中心的新功能:Android vitals。當app在大量裝置上執行時,Android vitals會收集與應用效能相關的各種匿名資料,比如:與app穩定性相關的資料、app啟動時間、電量使用情況、渲染時間以及許可權遭拒等等,這些資料會被分析整理後展示在Google Play管理中心的Android vitals dashboard中。Android vitals 中需要開發者重點關注的核心指標有:crash率、ANR率、excessive wakeups(過渡喚醒)、stuck wake locks(喚醒鎖定卡住)。其他指標,需根據應用型別選擇性關注(Android vitals中的指標總覽見圖1-1)。若app某些指標表現很差,會影響使用者體驗,並且會導致應用在Google Play商店中的等級很低、排名靠後(APP指標異常示例圖見圖1-2)。開發者可以通過分析Android vitals中提供的一些參照指標,採取相應的措施來優化app。
圖1-1 Android vitals平臺檢測指標總覽
圖1-2 某APP指標異常示例圖
2、核心指標詳細資訊:
要對APP的指標進行監控,首先要明確該指標在Android vitals中是如何進行統計的,這一節主要介紹電量相關核心指標的基本概念和計算方式。
2.1 Stuck partial wake locks(部分喚醒鎖定卡住)
A.WakeLock(喚醒鎖)基本概念:
Android系統本身為了優化電量的使用,會在沒有操作時進入休眠狀態, 來節省電量。為了便於開發(很多應用不可避免的希望在滅屏後還能執行一些事兒,或是要保持螢幕一直亮著--比如播放視訊),Android提供了一個PowerManager.WakeLock的東西。我們可以用WakeLock來保持CPU執行,或是防止螢幕變暗/關閉,讓手機可以在使用者不操作時依然可以做一些事兒。然而,獲取WakeLock很容易,釋放不好就會成為難題,消耗電量。
例如我們獲取了一個WakeLock來保持CPU運轉,做一個複雜運算並將資料上傳到後臺伺服器, 然後釋放該WakeLock。然而這個過程可能並不像我們想象的那麼快,可能因為比如伺服器掛掉,計算出了異常等等WakeLock沒有釋放。問題就來了,CPU會一直得不到休眠,而大大增加耗電。
喚醒鎖可劃分為並識別四種使用者喚醒鎖:
自 API 等級 17 開始,FULL_WAKE_LOCK 將被棄用。應用應使用FLAG_KEEP_SCREEN_ON。
相關連結:developer.android.com/reference/a…
B.Partial wake locks(部分喚醒鎖):
部分喚醒鎖可確保CPU正常執行,但螢幕和鍵盤背光可以關閉。如果執行在後臺的APP長時間持有某個部分喚醒鎖,就導致部分喚醒鎖卡住。這種情況十分消耗裝置電量,因為它會阻止裝置進入低電量狀態。Android vitals重點關注了stuck partial wake locks這項指標,當你的APP存在喚醒鎖定卡住的現象時,它會通過Play管理中心給出告警(APP出現部分喚醒鎖定卡住示例圖見圖2-1),並從各個維度給出相關的詳細統計圖(如圖2-2中給出每個工作時段後臺wake lock最長持續時間分佈圖)。當出現以下情況時,Android vitals會報告喚醒鎖定卡住:
- 至少70%以上的battery sessions發生過至少一次、長達一小時以上的部分喚醒鎖定。
- 當只在後臺執行時,至少10%以上的battery sessions發生過至少一次、長達一小時以上的部分喚醒鎖定。
(ps:battery session指兩次電池充滿電之間的時間間隔,Android vitals展示的battery sessions是所有app測試使用者的battery session合計。)
相關連結:developer.android.google.cn/topic/perfo…
圖2-1 某APP出現部分喚醒鎖定卡住(後臺)示例圖
圖2-2 每個工作時段後臺wake lock最長持續時間的分佈圖
2.2 Excessive wakeups(過渡喚醒)
A.Wakeups 基本概念
Wakeups 是AlarmManager API中的一種機制,開發者可以設定一個alarm在特定的時間來喚醒裝置。當某個喚醒alarm觸發,裝置會走出低電量模式,在執行alarm的onRecieve()或onAlarm()方法的時候,Alarm Manager會持有一個部分喚醒鎖。如果wake alarms頻繁觸發,會耗盡裝置電量。Android vitals中展示了app的過渡喚醒次數。
Alarm有以下四種型別:
1)RTC_WAKEUP
在指定的時刻(設定Alarm的時候),喚醒裝置來觸發Intent。
2)RTC
在一個顯式的時間觸發Intent,但不喚醒裝置。
3)ELAPSED_REALTIME
從裝置啟動後,如果流逝的時間達到總時間,那麼觸發Intent,但不喚醒裝置。流逝的時間包括裝置睡眠的任何時間。注意一點的是,時間流逝的計算點是自從它最後一次啟動算起。
4)ELAPSED_REALTIME_WAKEUP
從裝置啟動後,達到流逝的總時間後,如果需要將喚醒裝置並觸發Intent。
在Android vitals中只列出了RTC_WAKEUP和ELAPSED_REALTIME_WAKEUP兩種型別的喚醒資料,Google會統計每小時發生10次以上wakeup的電池工作時段百分比(APP發生過渡喚醒示例見圖2-3)。分別從應用版本、wakeup標記、裝置、Android版本等幾個維度統計每小時的Alarm Manager wakeup次數(每個工作時段中每小時的wackup分佈圖見圖2-4)。
圖2-3 某APP發生過渡喚醒示例圖
圖2-4 每個工作時段每小時wakeup次數分佈圖
3、測試方法研究
3.1 傳統電量測試方法回顧
我們之前也對騰訊視訊主線版本進行過電量測試,之前關注的重點在於APP在各場景中耗電量是否正常,是從比較巨集觀的角度去進行測試的,採取的測試方法主要是物理儀器測試法和GT測試法。
A.物理儀器測試法(電流表等)
在保持電壓恆定的情況下,獲取各場景平均電流值來統計系統耗電情況,通過此方法可以從大體上看出APP電量消耗是否正常,若儀器精度大,此方法測出的電量值是最準確的。
缺陷:此方法只能測試整個手機的電流,不能區分APP,受影響的因素多,如螢幕亮度大小、音量大小等等,要保證每次測試的環境完全一致是不可能的。
圖3-1 物理儀器測電量
B.GT測試法
GT(隨身調)是由MIG專項測試組自主研發的APP隨身調測平臺,它是直接執行在手機上的“整合調測環境”(IDTE, Integrated Debug Environment)。利用GT,僅憑一部手機,無需連線電腦,您即可對APP進行快速的效能測試(CPU、記憶體、流量、電量、幀率/流暢度等等)、開發日誌的檢視、Crash日誌檢視、網路資料包的抓取、APP內部引數的除錯、真機程式碼耗時統計等。
通過GT,可以採集手機耗電量相關資料:電流、電壓、電量、溫度等,通過分析這些資料,可以對整個手機的電量使用情況進行分析。
缺點:和物理儀器測試方法一樣,採用GT測試也只能獲取到整個手機的電量資料,無法只關注單獨APP,且受各種因素影響較大。
3.2 國際版電量測試方法預研
由於國際版APP在Google Play上釋出,我們做電量測試不僅僅需要關注整個APP的電量使用情況是否正常,還需要關注APP持有 wack lock和使用alarm的情況。因此,傳統的電量測試方法已經無法滿足我們的需求,我們需要在此基礎上增加額外的測試方法。
A.Batterystats/ bugreport
Android5.0後,電量資料可通過dumpsys batterystats獲取。Android系統統計耗電量的基本公式是W=UIt。在手機中,U一般恆定不變,因此可以單獨通過Q(電容量)=I*t來表示電量。核心類BatterStatsImpl提供App各部件執行時間、PowerProfile提供部件電流數值。Android部件電流資訊存於:power_profile.xml檔案中,每個OEM廠商都有私有的power_profile.xml檔案,PowerProfile通過讀取該檔案獲取訪問部件電流數值(圖3-3是samsung某型號的power_profile.xml)。Android系統以uid為單位,依次統計每個apk的使用cpu使用耗電量、wake lock耗電量、移動資料耗電量、wifi資料耗電量、wifi維持耗電量、wifi掃描耗電量、各感測器耗電量。其中wake lock消耗的電量只統計了持有Partial wake lock的耗電量,正好是我們需要關注的喚醒型別,因此我們可以通過分析batterystats獲得的電量資料來測試app持有Partial wake lock情況。
Android為了方便開發人員分析整個系統平臺和某個app在執行一段時間之內的所有資訊,專門開發了bugreport工具。bugreport檔案中記錄了系統允許過程中的各種log資訊,其中也包括了耗電量資訊。通過分析bugreport中的電量相關資料也能獲取APP持有Partial wake lock的資訊。
ps:Uid與App關係:2個App簽名和sharedUserId相同,則在執行時,他們擁有相同Uid。就是說processAppUsage統計的可能是多個App的耗電量資料,對於普通App,出現這種情況的機率較少,而對於Android系統應用則較為常見。
圖3-2 wack lock耗電量計算原始碼
圖3-3 sumsung某型號power_profile.xml
資料準備:
- 先斷開adb服務,然後開啟adb服務。
(1)adb kill-server
(2)adb start-server
由於開發時做電量記錄時會開啟很多可能造成衝突的東西,為了保險起見,重啟adb命令。
- 重置電池資料、收集資料
(3) adb shell dumpsys batterystats --enable full-wake-history
(4) adb shell dumpsys batterystats --reset
(5) adb shell logcat -c
通過以上命令來開啟電池資料的獲取以及重置,清除干擾的資料,清除歷史日誌。
- 獲取電量報告
把資料線拔掉,防止資料線造成充放電資料干擾。然後做一些測試的case,經過一段時間後,重新連線手機確認adb連上了,執行以下命令來將bugreport的資訊儲存到txt檔案中。
(6) adb bugreport >D:/bugreport.txt
或者用下面的命令也可以,官網上記述的內容,經實踐,無法被讀取…
(7) adb shell dumpsys batterystats > batterystats.txt
(8) adb shell dumpsys batterystats > com.example.app(包名) >batterystats.txt
ps:在此注意一定要等到該條命令執行完(稍微會有些慢)後,再開啟bugreport.txt檔案,之前遇到過沒有匯出完,就點開,資訊缺失的情況,導致無法成功生成圖表。
B.battery historian
生成的bugreport檔案有的時候異常龐大,能夠達到15M+,想一想對於一個txt文字格式的檔案內容長度達到了15M+是一個什麼概念,如果使用文字工具開啟檢視將是一個噩夢。因此google針對android 5.0(api 21)以上的系統開發了一個叫做battery historian的分析工具,這個工具就是用來解析這個txt文字檔案,然後使用web圖形的形式展現出來,這樣出來的效果更加人性化,更加可讀。我們可以使用該工具對bugreport檔案進行解析,更輕鬆的獲取電量相關資料。
battery historian的安裝可以參考以下連結:
developer.android.com/studio/prof…
也可以直接使用線上版本:
資料分析:
(1)選擇騰訊視訊app
(2)Wacklocks表格中展示app持有的wacklock,持有時間及數量,通過這個表格我們可以看到我們APP是否有持有一小時以上的wack_lock。
(3)Wakeup alarm info表格中展示了APP執行過程中觸發的wakeup alarm名字和個數,通過該分析工具也可以統計app的鬧鐘喚醒次數。
C.QAPM
QAPM是SNG開發的致力於解放專項測試人員的工具平臺,該平臺帶有電量監控功能,在電量個例選單中會統計前臺30分鐘、後臺5分鐘兩個場景下的wacklock持有資訊。該平臺上的資料可以作為我們電量測試的參考物件,具體的統計方法還需後續深入瞭解。
D.dumpsys命令
Android提供的dumpsys工具能夠用於檢視感興趣的系統服務資訊與狀態,手機連線電腦後能夠直接命令列執行adb shell dumpsys 檢視電池、電量相關資訊。
- adb shell dumpsys power
通過該條命令可以看到手機中所有的wack_lock持有資訊
- adb shell dumpsys alarm
此命令會提供裝置上的alarm系統服務相關資訊。其中Alarm Stats列出了應用設定alarm的情況,其中有系統被該應用所有alarm消耗的時間以及被鬧鐘喚醒的次數。可以通過獲取一小時內的電量資料來分析使用者在每小時的喚醒次數。
相關連結:blog.csdn.net/memoryjs/ar…
該方法與通過burgreport檔案統計電量資訊類似,都是通過Android系統中提供的工具來輸出電量的消耗情況,且該種方式輸出的報告也比較複雜,可讀性查,可在測試過程中作為參考。
4、國際版電量測試方法總結與實踐
4.1 測試方法總結
- 根據上一節的測試方法研究,我們打算首先用GT測試各個場景中APP電量消耗是否有異常。
- 接下來採用battery historian分析工具對手機裡獲取的bugreport檔案進行分析,統計app中持有超過一小時的wack_lock和一小時內發生的wackup數。
- QAPM中採集到的資料作為我們的輔助分析資料,我們可以比較兩份資料,看我們通過battery historian統計的wack_lock資料是否準確。
- 我們也可以通過使用dumpsys命令,檢視app電量相關資訊作為測試輔助方法。
4.2 測試方法實踐
騰訊視訊國際版1.0.0已經發布,我們已經使用該方法對其進行了一次電量測試,具體測試過程如下:
A.GT測試:
測試場景:啟動-播放-前臺靜置
測試機器:nexus
測試結果分析:
- 從以下電流趨勢變化圖中可以看出,播放過程和前臺靜置過程,電流曲線平穩,無較大波動,無明顯異常。
- 從播放到退出播放前臺靜置,使用電流明顯變小,符合預期。
B.Battery Historian測試:
測試場景:
- app前臺靜置2小時
- app後臺靜置2小時
- 全屏播放2小時
測試型號:
- Y7 Pro 2018 (LDN-LX2)
- OPPO F7 (CPH1819)
測試結果分析:
- 三個場景中,僅播放場景下會持有WindowManager這個wakelock超過1小時以上。而Android Vitals中關注的是app執行在後臺時,長時間持有部分喚醒鎖的情況,播放這個場景可以排除在外,因此得出結論,國際版APP持有喚醒鎖情況正常。
場景 | 機型 | 持有1小時以上的wack lock |
---|---|---|
app前臺 | 華為Y7 Pro 2018 (LDN-LX2) | 無 |
OPPO F7 (CPH1819) | 無 | |
app後臺 | 華為Y7 Pro 2018 (LDN-LX2) | 無 |
OPPO F7 (CPH1819) | 無 | |
全屏播放 | 華為Y7 Pro 2018 (LDN-LX2) | WindowManager |
OPPO F7 (CPH1819) | WindowManager |
\2. 測試過程中沒有統計到alarm資料,說明國際版APP暫時沒有使用到AlarmManager定時任務。
C.測試結論:
- GT電流測試顯示國際版APP各應用場景電量使用情況正常。
場景 | 啟動APP | 播放 | 退出播放,前臺靜置 |
---|---|---|---|
結論 | 啟動過程需載入圖片等資源,電流較大,正常 | 播放過程電流平穩無異常 | 退出播放電流變小,靜置過程平穩無異常 |
\2. Battery Historian分析電量資料得出,前臺靜置、後臺靜置、播放三個場景中僅播放場景會持有wack lock1小時以上,不屬於Android Vitals統計範疇,不會影響到國際版APP在Google Play商店的排名。
場景 | 機型 | stuck wake locks | excessive wakeups | 結論 |
---|---|---|---|---|
前臺靜置 | 華為Y7 Pro | 無喚醒鎖定卡住 | 無過渡喚醒 | 正常 |
OPPO F7 | 無喚醒鎖定卡住 | 無過渡喚醒 | 正常 | |
後臺靜置 | 華為Y7 Pro | 無喚醒鎖定卡住 | 無過渡喚醒 | 正常 |
OPPO F7 | 無喚醒鎖定卡住 | 無過渡喚醒 | 正常 | |
播放 | 華為Y7 Pro | 持有喚醒鎖1小時以上 | 無過渡喚醒 | 正常 |
OPPO F7 | 持有喚醒鎖1小時以上 | 無過渡喚醒 | 正常 |
5、總結與展望
由於騰訊視訊國際版目前功能比較少,用到wack_lock和alarm的情況比較少,我們只測試了前臺靜置、後臺靜置、播放三個場景,電量測試的結果也顯示APP電量使用情況正常,無部分喚醒鎖定卡住和過渡喚醒的情況出現,後續國際版功能會日漸豐富,可能需要補充push、下載等測試場景,持有wack_lock和alarm的情況也會更加複雜,因此我們會根據實際情況不斷改進和完善我們的電量測試方法。
此文已由騰訊雲+社群在各渠道釋出
獲取更多新鮮技術乾貨,可以關注我們騰訊雲技術社群-雲加社群官方號及知乎機構號