關于App UI性能的測試,Android提供了一個原生的工具Systrace,正常渲染FPS一般是在60左右,但是如果有一些代碼寫的不好,可能會影響到UI的性能,導致界面卡頓,這種問題是最難查的,為什么會卡頓,在哪卡頓,當然你也可以打log看時間,但是畢竟不方便。Systrace是可以解決這個問題的,我在網上查了一下關于Systrace的資料,還是比較少的,也許用的人也少吧。所以本文大部分內容翻譯自谷歌官方文檔
準備工作
首先如果你要運行Systrace,需要安裝Python和Android SDK Tools 20 以上的版本。
同時,現在Systrace只支持Android4.1以上的版本。
開始記錄
關于記錄有兩種方式開啟,一種就是使用Python,另外一種就是使用AndroidStudio中的自帶插件。
這里有一個問題,我不確認,是否使用AndroidStudio中的自帶插件也需要安裝Python,因為我的電腦一直安裝著這些東西,所以,可以直接運行。
Python 啟動
首先命令行切換到Android SDK的platform-tools下,在這個文件夾下有一個systrace文件夾,然后切到這個文件夾下:
在這個文件夾下有一個python腳本,運行即可。
python systrace.py --time=10 -o mynewtrace.html sched gfx view wm
運行規則如下:
參數名 | 意義 |
---|---|
-h,--help | 幫助信息 |
-o <FILE> | 保存的文件名 |
-t N,--time=N | 多少秒內的數據,默認為5秒,以當前時間點往后倒N個時間 |
-b N,--buf-size=N | 單位為千字節,限制數據大小 |
-k <KFUNCS> --ktrace=<KFUNCS> | 追蹤特殊的方法 |
-l,--list-categories | 設置追蹤的標簽 |
-a <APP_NAME>,--app=<APP_NAME> | 包名 |
--from-file=<FROM_FILE> | 創建報告的來源trace文件 |
-e <DEVICE_SERIAL>,--serial=<DEVICE_SERIAL> | 設備號 |
標簽簡寫:
簡寫 | 全稱 |
---|---|
gfx | - Graphics |
input | - Input |
view | - View |
webview | - WebView |
wm | - Window Manager |
am | - Activity Manager |
sync | - Synchronization Manager |
audio | - Audio |
video | - Video |
camera | - Camera |
根據官方文檔的意思,這些標簽在SDK 17以下需要使用
--set-tags = <TAGS>
進行添加,SDK18以及更高直接用簡寫即可,這個標簽表示生成性能分析結果中的標簽,這個后面再看。
Android Studio啟動
打開Android Studio:
點擊如圖所示的標簽,打開Android Device Monitor這個界面,在左上角選擇如下按鈕:
然后進入可視化設置界面:
進行設置,點擊ok,便可開始記錄。
數據分析
我這里將會使用命令行模式進行數據記錄。
在記錄之前,我先寫了一個簡單的demo,demo有三個Activity,一個主界面,一個放有listview的Activity,一個放有RecyclerView的Activity(代碼很基礎我就不貼出來了)
在listview中我加入了1000個Item,每個item中都有文字和圖片,RecyclerView也是。特別注意,listview沒有做任何優化,因為我們要看的就是不好的效果。我先運行一下程序,然后在命令行中輸入如下:
python systrace.py --time=20 -o deep.html -a deep.testsystrace sched gfx view wm
我記錄了20秒內的情況,指定包名deep.testsystrace,生成文件deep.html,運行,然后不斷滑動listview:
直到記錄結束,命令行會有如下提示:
然后我們打開這個文件夾,找到剛才生成的deep.html。
打開這個網頁:
在分析這些數據之前,我們需要先知道一些操作:
Key | Description |
---|---|
w | Zoom into the trace timeline. |
s | Zoom out of the trace timeline. |
a | Pan left on the trace timeline. |
d | Pan right on the trace timeline. |
e | Center the trace timeline on the current mouse location. |
g | Show grid at the start of the currently selected task. |
Shift+g | Show grid at the end of the currently selected task. |
Right Arrow | Select the next event on the currently selected timeline. |
Left Arrow | Select the previous event on the currently selected timeline. |
我們在網頁中找到我們的工程,deep.testsystrace,但是不知道是不是bug,網頁只顯示了ep.testsystrace,不過根據pid也可以確認就是我們的應用。
之后我們逐個分析,首先是Frames,即幀數。我們將上圖放大(快捷鍵w):
可以看到幀數對應的一行有許多F,各種顏色:
當顯示為綠色的時候為正常,紅色或者黃色分別對應的等級是e和w,也就是不正常,即達不到60fps的水準。這是我們就可以根據下面的時間分析到底是什么占用的時間了。
首先點擊紅色即不正常的F:
與該幀無關的操作會被置成灰色:
然后將其逐漸放大:
對比正常的幀,我們可以發現,我們obtainView和inflate調用過多。我們之前說了,listview我們沒有做任何優化,每次都會重現建立view,也沒有使用viewholder,所以會出現如上結果。如果我們對listview進行了優化呢?我們可以試一下,修改一下adapter的getview,當view為空時再進行創建。然后再次記錄數據:
我們發現已經沒有紅色的F了,但是仍有少數黃色的F,我們可以根據分析再次進行優化,加上ViewHolder。這里不再做測試了。
同樣我們也可以根據Alert中的提示進行修改,但是感覺提示不能直指原因,還是分析幀數,更容易找到原因。
自定義記錄
我們還可以通過Trace.beginSection來記錄一些信息,如下代碼:
Trace.beginSection() 與 Trace.endSection() 之間代碼工作會一直被追蹤。結果如下,為了查看方便我把結果放大了:
可以以這種方式查看某個程序塊的耗時。
總結
用這種方式可以分析出app 卡頓的一些問題的原因,從而進行解決。對于app開發人員,還是掌握較好。
更多的開發知識,可以關注我的公眾號: