Andorid性能優化之traceview的使用

一、traceview的使用方式有2種方式

這2種方式可以根據場景,去選擇哪一種方式。最終效果是一樣的

  • 通過手動埋點
  • Profile

1.1、通過手動埋點。

步驟1: 比如我們知道在點擊一個按鈕的時候,會有卡頓,那麼就可以用

//可以用以下代碼測試你的代碼。
//開始埋點,“app”是最後生成的性能分析文件
Debug.startMethodTracing("App");

//埋點結束,期間start 到 stop 之間的代碼,就是你要測試的代碼範圍
Debug.stopMethodTracing();

 

步驟2: 運行完測試代碼後,我們點開studio右下角的Device Explorer,在下圖的“第一步”,打開之後我們要找到我們生成的trace文件,路徑在sdcard/Android/data/項目包名/files,如圖:

 

 

步驟3: 直接左鍵雙擊可以打開我們的文件如圖:

 

部分1:是時間選擇範圍,整段就是我們剛剛用代碼埋點指定的。上面的時間標誌是時間戳。
部分2:表示當前埋點的代碼有5個線程。可以點擊任何一個線程查看
部分3:這裏有4個按鈕

  • Call Chart
  • Flame Chart
  • Top Down
  • Bottom Up

接下來我們具體看看這四個按鈕

1.1.1、Top Down

點開我們的Top Down,如下:

 

紅色框1: 表示main裏的一些情況。

  • Total:表示main函數所有執行需要的時間
  • Self: 表示main函數裏,除了調用別的函數方法外,自己方法內代碼的執行時間
  • Children: 表示mian函數裏,調用別的函數所執行的時間
     

紅色框2: 裏面有2個選項,可以切換成Wall Clock Time或者Thread Time

  • Wall Clock Time:指這個線程真正的執行時間,比如消耗了100ms就是消耗了100ms
  • Thread Time:CPU的執行時間,比Wall Clock Time少。

爲什麼這兩個時間會不一樣?舉個不恰當的比喻,比如運行一個方法,因爲鎖的原因,線程等待。這個時候等待時間也算在了Wall Clock Time裏。 但是Thread Time是CPU的執行時間,線程閒置的時候並沒有消耗CPU,當然這個等待時間也就不算在Thread Time裏了。

紅色框3: 表示方法的依次調用。及每個子方法調用所消耗的時間。這裏也可以看成是Call Chart表的“代碼化”。

1.1.2、Call Chart

點開Call Chart如下:

 

 

這裏注意要注意幾點:

  • 這裏的圖標表示,比如2個方法A和B。方法A調用方法B,那麼方法A就在方法B的上方。
  • 橙色:表示系統API方法調用
  • 綠色:表示自身方法調用
  • 藍色:表示第三方調用

1.1.3、Flame Chart

點開Flame Chart後,如下:

 

這裏的意思是會把相似或相同的方法統計在一起,比如A方法調用B方法調用C方法:A->B->C,那麼他會將所有按此順序的方法收集在一起,或者將A->B->D也會收集在上,橫軸表示的是相對時間。

1.1.4、Bottom Up

點開Bottom Up如下

 

這裏點開initX5web() -> 顯示了main();也就是說誰調用了我。main()方法裏調用initX5web();

1.2、通過Andorid studio 的Profile

點擊Profile運行項目

 

運行後如下圖:

 

鼠標移動到CPU那裏後,左鍵雙擊CPU後,如圖:

 

可以看到,這裏和我們上面用代碼埋點界面幾乎相同了,這裏有個按鈕,Record,點擊後,文案會變成stop;我們就可以在APP裏操作,來到我們覺得卡頓或者有問題的功能裏。點擊stop就形成了我們trace一樣的文件裏。裏面的操作都是一樣的

 

 

二、我們來舉個小例子,來解決一項卡頓

拿以前做的一個項目舉例,爲了不被騷擾,這裏我隱藏了手機號。看看下面的gif,這裏我在輸入密碼後,點擊登錄,在網絡請求結束後,dialog已經消失了,還沒有跳轉到我們的首頁,如圖,此時有明顯的卡頓

Sample
 

在我們logcat裏過濾關鍵字:Displayed 可以看到我們程序中每個Activity的啓動時間,此時我的啓動時間是996,接近1s(fuck,這樣都有996,擦):

Sample

這個時候我們用第二種方式去嘗試解決這個卡頓,根據我們的Top Down分析,根絕Total的耗時時間,我們一直往下點,首先來到如下(假設我們還不知道是跳轉Activity卡頓):

 

這時候到了2個方法,dispatchMessage()和next();
我們先將dispatchMessage點到底,看到了setContentView()裏的loadDrawable()。可以看到這個是元兇

 

將next()點到底,如圖,在nativePollOnce(),後子方法裏,沒有耗時項,根據方法名也能猜測到,這是系統方法。

 

由上面的分析,最終問題定在了setContentView()裏的loadDrawable()。也就是說明我們MainActivity的layout裏,不管是src還是background,有一個非常耗時的bitmap。這裏我照下來之後,確實發現了根佈局的background裏背景大圖,我這裏直接取消這張圖後,運行程序,如下,可以發現不再卡頓了,而且跳轉速度大大提升了:

Sample

打印下時間,啓動時間由原來的996,變成了447:

Sample
這裏我只是舉了個小例子,希望對學習性能優化的朋友有幫助。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章