使用Systrace分析UI性能
翻譯原文地址:https://developer.android.com/studio/profile/systrace.html
在開發(fā)應(yīng)用時,通常使用60fps的幀率來檢測交互是否流暢,如果中途出錯了,或者發(fā)生了掉幀,解決這個問題的第一步應(yīng)當(dāng)是搞清楚當(dāng)前系統(tǒng)在做什么。
Systrace工具可以在程序運行的時候收集實時的信息,記錄時間以及CPU的分配情況,記錄每個線程和進(jìn)程在任意時間的運行情況,可以自動分析出一些重要的原因,并且給出建議。
預(yù)覽
Systrace可以幫助你分析應(yīng)用是如何設(shè)備上運行起來的,它將系統(tǒng)和應(yīng)用程序線程集中在一個共同的時間軸上,分析systrace的第一步需要在程序運行的時間段中抓取trace log,在抓取到的trace文件中,包含了這段時間中你想要的關(guān)鍵信息,交互情況。
圖1顯示的是當(dāng)一個app在滑動時出現(xiàn)了卡頓的現(xiàn)象,默認(rèn)的界面下,橫軸是時間,縱向為trace event,trace event 先按進(jìn)程分組,然后再按線程分組.
從上到下的信息分別為Kernel,SurfaceFlinger,應(yīng)用包名。通過配置trace的分類,可以根據(jù)配置情況記錄每個應(yīng)用程序的所有線程信息以及trace event的層次結(jié)構(gòu)信息。
生成trace
首先需要一些準(zhǔn)備工作:
第一,android 4.1及以上的設(shè)備
第二,開啟調(diào)試模式,安裝你的應(yīng)用
第三,某些trace信息需要root權(quán)限才能夠獲取,比如 disk activity和工作隊列等,但是大部分都不需要root權(quán)限。
systrace的追蹤有兩種方式:一種是通過命令行,一種是通過圖形界面,可以查看http://www.lxweimin.com/p/0670fe8507ff。
android4.3及以上
通過以下命令獲取:
$ cd android-sdk/platform-tools/systrace
$ python systrace.py --time=10 -o mynewtrace.html sched gfx view wm
android4.2及以下
在低于android4.2的設(shè)備上,需要事先做一些配置,當(dāng)你需要收集如下信息是:
- 收集graphics,aduio以及輸入進(jìn)程信息(通過配置--set-tags=<TAGS> 獲取)
- 收集CPU,disk,kernel以及dish activity信息(通過配置option來獲取)
通過命令行來配置tages
- 使用 --set-tags選項:
$ cd android-sdk/platform-tools/systrace
$ python systrace.py --set-tags=gfx,view,wm
- 關(guān)閉、重啟adb
$ adb shell stop
$ adb shell start
通過圖形界面
- 在android設(shè)備的 設(shè)置 -- 開發(fā)者選項 -- 監(jiān)控 -- 開啟traces
- 選擇要追中的類別,并且點擊確定
注意:無需重啟adb服務(wù)
完成以上配置后,開始抓trace文件
$ python systrace.py --cpu-freq --cpu-load --time=10 -o mytracefile.html
分析trace文件
抓到trace.html文件后,通過web瀏覽器打開
檢查Frames
每個應(yīng)用程序都有一排代表渲染幀的圓圈,通常為綠色,如果繪制的時間超過16.6毫秒則顯示黃色或紅色。通過“W”鍵查看幀。
注意:輸入“?”可以查看幫助
點擊幀,則下方將顯示系統(tǒng)為該幀所做的工作。在運行Android 5的設(shè)備(API Level 21)或更高,這項工作分為UI線程和render線程。而在以前的版本中,創(chuàng)建幀的所有工作都是在UI線程上完成的。
點擊幀的各個組件,可以查看它們的運行時間,事件(如performtraversals),當(dāng)你選擇某個方法時,也會顯示該方法的執(zhí)行過程。點擊最下方的alert,將顯示alert的具體信息。
Alerts的審查
Systrace會自動分析trace event,在alerts中指出性能問題,并且給出相應(yīng)的建議。
選擇慢幀(如圖3的黃色圓圈所示)之后,將在底部顯示一個警報。在Description一欄中,將看到變慢的原因(ListView在回收和重繪的時候,由于超負(fù)荷的工作導(dǎo)致慢幀),trace中有相關(guān)事件的鏈接,可以進(jìn)一步解釋系統(tǒng)在這段時間內(nèi)正在做什么。
如果許多ListView工作都在UI線程中進(jìn)行的,那么你可以使用Traceview(https://developer.android.com/studio/profile/traceview.html)代碼性能能分析工具,分析具體是在哪一些方法耗時過多。然后,在這些方法上添加trace marker(可參見下一節(jié)的見trace應(yīng)用程序代碼)的功能獲得更具體的定位。
注意,您還可以通過單擊窗口右側(cè)邊的Alert選項卡來查找trace中的每個警報,在彈出的側(cè)邊框中那里您可以看到trace中警告以及事件計數(shù)。
Alert面板會將trace中的問題呈現(xiàn)出來,以及這些問題造成卡頓的頻率,
幫助你看到問題發(fā)生的痕跡,以及如何他們往往有助于該。Alert面板可以看成一個是待修復(fù)的bug列表,通常一個區(qū)域的微小變化或改進(jìn)可以消除應(yīng)用程序中的所有類警報!
trace應(yīng)用程序代碼
在framework中的trace marker并沒有覆蓋到你的所有代碼,因此有些時候你需要自己去定義trace marker。在Android4.3之后,可以通過Trace類在代碼中添加標(biāo)記,這樣你將能夠看到在指定時間內(nèi)應(yīng)用的線程在做哪些工作,當(dāng)然,trace 的begin和end操作也會增加一些額外的開銷,但都只有幾微秒左右。
通過下面的例子來說明Trace類的 用法。
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
...
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Trace.beginSection("MyAdapter.onCreateViewHolder");
MyViewHolder myViewHolder;
try {
myViewHolder = MyViewHolder.newInstance(parent);
} finally {
Trace.endSection();
}
return myViewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Trace.beginSection("MyAdapter.onBindViewHolder");
try {
try {
Trace.beginSection("MyAdapter.queryDatabase");
RowItem rowItem = queryDatabase(position);
mDataset.add(rowItem);
} finally {
Trace.endSection();
}
holder.bind(mDataset.get(position));
} finally {
Trace.endSection();
}
}
…
}
注意:endSection和beginSection遵循就近匹配原則,因此注意控制他們的匹配順序。
注意:begin和end必須在同一個線程中。
注意:如果begin被try catch語句包含了,則endSestion必須放到finally語句塊中。
使用應(yīng)用程序級跟蹤Systrace時,您必須指定應(yīng)用程序包名。
在分析應(yīng)用程序時,你應(yīng)該啟用應(yīng)用程序級跟蹤,即使你沒有在你的應(yīng)用程序中添加你自己的跟蹤標(biāo)記。只有當(dāng)你開啟了應(yīng)用級別的trace,許多l(xiāng)ib庫,如recyclerview,包括trace marker才能提供有用的信息。