關於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 |
儲存的檔名 |
-t N,--time=N | 多少秒內的資料,預設為5秒,以當前時間點往後倒N個時間 |
-b N,--buf-size=N | 單位為千位元組,限制資料大小 |
-k |
追蹤特殊的方法 |
-l,--list-categories | 設定追蹤的標籤 |
-a |
包名 |
--from-file= |
建立報告的來源trace檔案 |
-e |
裝置號 |
標籤簡寫:
簡寫 | 全稱 |
---|---|
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開發人員,還是掌握較好。
更多的開發知識,或有什麼問題,可以關注我的公眾號,給我留言: