原文地址: http://blog.gaoyuan.xyz/2013/11/22/android-app-profile-tools/
如果一個android應用打開時比較慢,或者使用起來比較卡。這個可能是客戶端代碼有待優化,也可能是服務端性能比較挫。對一個客戶端開發者而言,在客戶端代碼中增加相關debug日誌,即可比較準確地定位問題。但這活要落到一個服務端開發人員手裏,要怎麼辦?
本文將在沒有apk源碼的情況下,以服務端開發人員的視角進行客戶端app性能的分析。
在分析之前,我們先補充點android基礎知識。
android基礎知識
我們所說的android應用,一般都是通過將一個以apk結尾的文件安裝在手機等移動設備上才能運行起來的。所以我們先從apk說起。
什麼是apk
我們先從網上下載一個apk
$ wget http://shouji.360tpcdn.com/131106/0124832c4cf8c35a762cfece3bac52b1/com.sina.weibo_650.apk
然後查看這個文件的類型
$ file com.sina.weibo_650.apk
com.sina.weibo_650.apk: Zip archive data, at least v2.0 to extract
會發現com.sina.weibo_650.apk
是一個zip壓縮文件。解壓縮後的文件,主要包括一些資源文件,一些配置文件,一些類庫,還有一個class.dex。目錄結構如下
AndroidManifest.xml
assets
classes.dex
lib
META-INF
org
res
resources.arsc
粗略一看,發現 class.dex
這個文件有5.9M,這應該就是主角。繼續執行如下命令
$ file classes.dex
classes.dex: Dalvik dex file version 035
因爲沒有開發過android應用,不明白用java開發的app和這個Dalvik dex file之間有什麼關係?所以我們先跳出apk的視角。
android平臺架構
如上圖,android基於linux操作系統,使用linux內核與設備的硬件進行交互。在內核之上,又抽象出了一層,包括Dalvik虛擬機等。
因爲dex
是Dalvik
VM
Executes的全稱,即android Dalvik
虛擬機執行程序。
那一個apk的生產和執行過程將是: *.java
-> *.class -> classes.dex(classes.dex將由Dalvik VM轉換成機器碼,由linux內核交給cpu去執行)
這樣的話,在linux系統上使用profile軟件的經驗,也將派上用場。
android相關基礎知識先介紹到此,感興趣的請進一步查閱本文後面的參看資料。
android應用性能分析
apk啓動速度
在分析之前,我們先看看android程序的執行流程
如上圖,只要獲取到啓動ActivityManager所需要的時間,即是apk的啓動時間。
adb logcat | grep ActivityManager
其中”Displayed”對應的時間,即是launch Activity對應的時間,也就是apk啓動時間,也可以使用如下命令:
adb logcat -c && adb logcat -s ActivityManager | grep "Displayed"
-
要使用
adb
,需要先用usb線連接電腦和手機,並在手機的設置
–>開發者選項
中開啓USB調試
-
adb
這個工具,可以通過在android sdk的platform-tools目錄中找到。後面介紹的systrace
也在這個目錄。
頁面渲染性能
android應用中的頁面,是由android系統一幀,一幀地繪製的,其中每一幀的處理如下圖:
即: 計算視圖大小(measure)
-> 安置視圖的位置(layout) -> 繪製(draw)視圖
通過收集每幀的處理時間,即可以瞭解頁面的渲染性能。
當fps(每秒處理幀數,頁面刷新率)爲60時,頁面的渲染看起來會比較平滑,這就需要每幀的處理時間不能大於16ms(1000/60)
要檢測一個應用在渲染頁面時的每幀處理時間,通過如下命令,即可獲得每幀的處理時間
adb shell dumpsys gfxinfo com.sina.weibo
在輸出日誌的Profile
數據段,包含了三列Draw
,Process
,Execute
分別對應的處理時間,單位是ms。這三列的總和,就是渲染每幀時的處理時間。如
Draw Process Execute
0.95 0.93 0.72
0.84 1.16 0.56
0.83 0.89 0.69
1.32 2.15 1.14
1.29 1.37 1.01
在進行分析之前,需要在
設置
–>開發者選項
中點擊GPU呈現模式分析
,選擇在adb shell dumpsys gfxinfo中
。
收集步驟:
1.重新啓動app
2.在界面完全加載完之後,在界面上慢慢上下滑動幾個像素
3.在終端執行adb shell dumpsys gfxinfo com.sina.weibo
這時將在終端輸出頁面渲染時的最後128幀中每幀所花費的時間,將相關數據貼到excel表格中,點擊其中的insert
–>chart
,即可生成相關圖表
其中
com.sina.weibo
就是app的包名
獲取包名的方法:
adb shell pm list packages
使用systrace進一步分析
通過收集該apk的啓動速度和每幀的渲染時間,並與竟品進行對比發現。該app啓動時間的確比較慢,也偶爾有丟幀的現象發生。如何近一步分析呢?這時就需要systrace
了。
示例使用方法如下:
cd android-sdk-linux/platform-tools/systrace
python systrace.py --app=com.qihoo.appstore gfx view
上面這條命令將會在android-sdk-linux/platform-tools/systrace
目錄下生成trace.html
。其中收集了包名爲com.qihoo.appstore
的應用在android系統上針對gfx
和view
category的執行數據。
trace.html
在瀏覽器中打開如下圖:
可以使用如下方法,對trace.html
進行進一步分析:
* 通過鼠標點擊左側的+
,-
可以展開或者收縮相關顯示數據
* 通過鍵盤上的a
,d
可以使顯示的內容沿着頂部的時間軸向左或者向右移動
* 通過鍵盤上的w
,s
可以對顯示的內容進行放大或者縮小
* 使用鼠標點擊內容頁面的某一個塊,在下方會顯示詳情 * 使用鼠標選擇一塊內容頁面,在下方會顯示彙總信息
將光標定位到最後一行,使用w
進行放大,使用d
向左移動到2260ms左右,如下圖:
發現對於那些performTraversals
處理超過16ms的幀,其中eglSwapBuffers
處理的時間都比較長,這應該就是問題所在。
使用usb線連接上手機,在命令行下運行:
python systrace.py -h
可以查看相關使用方法。
systrace是在在android4.1上新增的工具,在4.1,4.2和4.3上使用的方法不同
reference:
[^1] http://www.curious-creature.org/docs/android-performance-case-study-1.html
[^2] http://www.curious-creature.org/docs/android-performance-case-study-1.html
[^3] http://www.vogella.com/articles/AndroidTools/article.html
[^4] http://blog.csdn.net/aaa2832/article/details/7849400
[^5] http://www.cnblogs.com/taobox/articles/3405931.html
[^6] http://bigflake.com/systrace/
[^7] http://developer.android.com/tools/debugging/systrace.html
[^8] http://kitoslab-eng.blogspot.com/2013/01/aprof-android-profiler-profiling-tool.html