1.TraceView 是什么
TraceView 是AndroidSDK 中內置的一個工具,它可以加載trace文件,用圖形的形式展示代碼的執行時間、次數及調用棧,便于我們分析。
手機卡頓很多時候都是由于某個操作過于耗時,在茫茫代碼中查找元兇未免太過痛苦,這時候就該體現 TraceView 的價值了,通過traceview,可以知道時間都消耗在哪里了
生成 trace 文件有三種方法:
使用代碼
使用 Android Studio
使用 DDMS
這里我只分享下用DDMS生成
2、詳細操作步驟:
打開 Android Device Monitor,在 DDMS 中打開 trace 文件,DDMS 會啟動 TraceView 加載 trace 文件:
操作手機上出現問題的地方
3、分析生成的數據:
先分析上半部分
上半部分顯示了不同線程的執行時間
每種顏色代表不同的函數和步驟,同一顏色的區域越大,就代表這個步驟運行時間越長
程序中每個線程調用方法的啟動和停止時間
同一個顏色越長,說明執行時間越久,如圖中的主線程 main
空白表示這個時間段內沒有執行內容
右上角顯示程序總共運行了13400毫秒
縱軸
TraceView界面下方表格中縱軸就是每個方法,包括了JDK的,Android SDK的,也有native方法的,當然最重要的就是app中你自己寫的方法,有些Android系統的方法執行時間很長,那么有很大的可能就是你app中調用這些方法過多導致的。
下半部分展示了不同方法的執行時間信息,關鍵指標有三個:
Cpu Time/Call :該方法平均占用 CPU 的時間
Real Time/Call :平均執行時間,包括切換、阻塞的時間,>= Cpu Time
Calls + Recur Calls/Total :調用、遞歸次數
每個方法前面都有一個數字,可能是全部方法按照Incl CPU Time 時間的排序序號(后面會講到)
點一個方法后可以看到有兩部分,一個是Parents,另一個是Children。
Parent表示調用這個方法的方法,可以叫做父方法
Children表示這個方法中調用的其他方法,可以叫做子方法
橫軸
inclusive:就是說除統計函數本身運行的時間外再加上調用子函數所運行的時間
Exclusive:統計函數本身運行的時間
1. Incl Cpu Time
Incl Cpu Time表示方法top執行的總時間,假如說方法top的執行時間為10ms,方法a執行了1ms,方法b執行了2ms,方法c執行了3ms,方法d執行了4ms(這里是為了舉個栗子,實際情況中方法a、b、c、d的執行總時間肯定比方法top的執行總時間要小一點)。
publicvoidtop()?{
a();
b();
c();
d();
}
2. Excl Cpu Time
理解了Incl Cpu Time以后就可以很好理解Excl Cpu Time了,還是上面top方法的栗子:
方法top 的 Incl Cpu Time 減去 方法a、b、c、d的Incl Cpu Time 的時間就是方法top的Excl Cpu Time 了
3. Incl Real Time
這個感覺和Incl Cpu Time 差不多,第7條會講到。
4. Excl Real Time
同上
5. Calls + Recur Calls / Total
這個指標非常重要!
它表示這個方法執行的次數,這個指標中有兩個值,一個Call表示這個方法調用的次數,Recur Call表示遞歸調用次數,看下圖:
我選中了一個方法,可以看到這個方法的Calls + Recur Calls值是1 + 17,表示這個方法調用了1次,遞歸調用17次
。
6. Cpu Time / Call
重點來了!!!!!!!!!!
這個指標應該說是最重要的,從上圖可以看到,這個方法的調用次數為3次,而它的Incl Cpu Time為251.793ms,方法調用了3次,所以每一次的時間為83.913(也就是Cpu Time)
getView方法執行時間很長,那么必然導致列表滑動的時候產生卡頓現象,可以在getView方法的Children方法列表中找到耗時最長的方法,分析出現問題的原因:
是因為有過多的計算?
還是因為有讀取SD卡的操作?
還是因為adapter中View太復雜了?
還是因為需要有很多判斷,設置View的顯示還是隱藏
還是因為其他原因…
7. Real Time / Call
Real Time 和 Cpu Time 我現在還不太明白它們的區別,我的理解應該是:
Cpu Time 應該是某個方法占用CPU的時間
Real Time 應該是這個方法的實際運行時間
為什么它們會有區別呢?可能是因為CPU的上下文切換、阻塞、GC等原因方法的實際執行時間要比Cpu Time 要稍微長一點。
下半部分展示了不同方法的執行時間信息,關鍵指標有三個:
Cpu Time/Call :該方法平均占用 CPU 的時間
Real Time/Call :平均執行時間,包括切換、阻塞的時間,>= Cpu Time
Calls + Recur Calls/Total :調用、遞歸次數
點擊下面的任意一個方法,可以看到它的詳細信息:
Parents:選中方法的調用處
Children:選中方法調用的方法
根據 TraceView 顯示內容定位問題
定位問題時 TraceView 的使用方式:
從上半部分查看哪些線程執行時間長?什么時候開始執行?與主線程交錯時間?
哪些方法的執行需要花費很長時間
點擊 TraceView 中的 Cpu Time/Call,按照占用 CPU 時間從高到低排序
哪些方法調用次數非常頻繁
點擊 TraceView 中的 Calls + Recur Calls/Total ,按照調用次數從高到底排序
排序后,然后逐個排查是否有項目代碼或者依賴庫代碼,有的話點擊查看詳情,查看是這個方法還是調用的子方法的問題,進一步定位問題。
實例:
可以看到項目中我們寫的方法的耗時,可以點進去,看child,查找時間消耗去向
1)
經由上圖可以發現,HouseListTask的doInBackground方法的時間消耗在UtilsLog和解析上了
2)GetHouseTrueCountAsynTask的doInBackground方法的時間消耗在了HttpClient.execute上了
GetHouseTrueCountAsynTask的onPostExcute方法的時間消耗在cacheToDisk這個方法上
3)getview方法時間消耗在inflate方法上了