【工利其器】必會工具之(三)systrace篇(1)官網翻譯

前言html

       Android 開發者官網中對systrace(Android System Trace)有專門的介紹,本篇文章做爲systrace系列的開頭,筆者先不作任何介紹,僅僅翻譯一下官網的介紹。在後續的文章中再整理一份學習教程,以及筆者的實踐經歷。官網中對該工具的介紹文檔路徑爲【https://developer.android.google.cn/studio/command-line/systrace?hl=en#java】。或者在進入到官網的首頁後,按照Android Developers > Android Studio > USER GUIDE > Command line tools > systrace的路徑訪問該文檔。java

       該文檔主要包含以下內容:python

 

1、systrace簡述android

       systrace命令容許你收集和檢查在你的設備上運行的全部系統級別進程的定時信息。它聯合Android內核(好比CPU調度程序)、磁盤活動和app線程,生成一份HTML報告,如圖1所示:web

  圖1:一個systrace的HTML報告案例,它顯示了與app 5秒鐘的交互。這份報告高亮顯示了那些systrace認爲可能沒有被適當地渲染的幀。瀏覽器

       這份報告提供了一份在給定時間段內Android設備系統進程的全局圖。它也檢查了被捕獲的追蹤信息,用於高亮顯示它觀察到的問題,好比顯示動做或動畫時的UI jank(筆者注:界面來不及刷新致使的卡塞空白現象),以及提供修復這些問題的建議。可是,systrace不會收集在app進程內與代碼執行相關的信息。 關於你的app正在執行哪些方法以及它佔用了多少CPU資源的詳情,請查看 【Android Studio CPU profiler】。你也可使用CPU Profiler來生成追蹤日誌,導出並檢查它們。緩存

       這份文檔解釋了怎樣從命令行生成systrace報告,操做由工具生成的trace文件,而且使用它們分析及改善應用的UI性能。網絡

★注意:在運行於Android 9(API level 28)或者更高的設備上,你可使用一個叫作System Tracing的系統app在設備上記錄system trace。

      爲了運行systrace,請完成下面的步驟:app

      systrace工具在Android SDK Tools 包中提供,其路徑爲 android-sdk/platform-tools/systrace/ide

 

2、語法

       爲了給app生成HTML報告,你須要在命令行中使用以下的語法運行systrace:

$python systrace.py [option][categories]

       例如,以下的命令行調用了systrace用於記錄設備活動,而且生成一份名爲 mynewtrace.html 的HTML報告。該categories列表對大多數設備而言是一個合理的默認列表。

$ python systrace.py -o mynewtrace.html sched freq idle am wm gfx view \ binder_driver hal dalvik camera input res
★ 提示:若是你想看輸出的trace中任務的名字,你的命令參數中必須包含「sched」 category。

 想查看你鏈接的設備所支持的category列表,請運行下面的命令:

$ python systrace.py --list-categories

 若是你沒有指定任何的category或者option,systrace會生成一個包含全部可用category的報告而且使用默認的設置。這些可用的category依賴於你所鏈接的正在使用的設備。

  一、全局option

 

全局option 描述
-h | --help 顯示幫助信息
-l | --list-categories 列出你鏈接的設備所支持的可用category

  二、命令和命令選項

Commands and options Description
-o file 把HTML trace報告寫入到指定file。若是你不指定這個選項,systrace將會把你的報告保存到和systrace.py相同的根目錄下,而且命名爲trace.html。
-t N | --time=N 追蹤設備活動N秒鐘。若是你不指定該選項,systrace將會提示你在命令行中按Enter鍵結束追蹤。
-b N | --buf-size=N 使用一個大小爲N KB的trace緩存。這個選項可讓你限制追蹤過程當中收集的數據的大小。
-k functions
| --ktrace=functions
追蹤指定內核函數的活動,在一個以逗號隔開的列表中列出。
-a app-name
| --app=app-name

 激活追蹤app,這些app在以逗號分隔的進程名列表中被指定列出。這些app必須包含來自於Trace 類的追蹤檢測調用。

不管什麼時候你profile你的應用,你都應該指明這個選項,不少庫(好比RecyclerView)都包含了追蹤檢測調用,

當你激活應用級別的追蹤時,這些調用提供了有用的信息。想了解更多信息,請閱讀關於怎樣「檢測你的app代碼」這部份內容。

--from-file=file-path 從文件當中建立一個交互式的HTML報告,好比包含原始trace數據的TXT文件,而不是運行實時追蹤。
-e device-serial
| --serial=device-serial
在指定鏈接的設備上進行追蹤,該設備由設備序列號來識別。
categories 包含你所指定的系統進程的追蹤信息,好比gfx表示用於圖像渲染的系統進程。你能夠經過加上 -l 命令運行systrace來查看你所鏈接的設備上可用的服務列表。

 

3、調查用戶界面性能問題

       systrace 在檢查你的app的用戶界面性能方面尤爲有用,由於它可以分析你的代碼和幀率來驗證問題區域和建議可能的解決方案。首先,按照以下步驟進行:

      1)在你鏈接的設備上運行你的app。

      2)用下面的命令運行systrace,

$ python systrace.py -t 10 [other-options] [categories]

       這個例子會追蹤你的app 10秒鐘。

      3)當systrace正在運行的時候,和你的app進行交互(筆者注:即操做你的app)。

      4)在你定義的限定時間過去後,好比該例中的10秒,systrace會生成一個HTML 報告。

      5)使用一個web瀏覽器打開這份HTML報告。

       經過和這份報告交互,你能夠檢查設備在這段記錄時間內的CPU使用狀況。爲了幫助操做HTML報告,請查看「鍵盤快捷鍵」這一部分,或者點擊報告右上角的"?"按鈕。

       下面這一部分解釋了怎樣檢查報告中的信息,從而找到並修復UI性能問題。

  一、檢查幀和警告

       如圖2所示,報告列出了每個渲染UI幀的進程而且沿着時間線指出了全部的渲染幀。這些幀在16.6毫秒內渲染一幀, 須要維持一個穩定的每秒60幀的幀率,在報告中他們用綠色的圓圈表示。那些渲染超過16.6毫秒的幀則用黃色或者紅色圓圈表示。

圖2:長時間運行的幀放大後的systrace顯示

★ 注意:在運行版本爲Android5.0(API level 21)或更高的設備上,UI線程和渲染線程之間用於渲染幀的工做是分離的。在以前的版本中,建立幀的全部工做都是在UI線程中完成的。

       點擊一個Frame圓圈(帶有F標記的圓圈,後面簡稱圓圈)會讓它變成高亮而且提供額外的信息,這些信息是關於系統渲染這一幀作所的工做,包括警告。同時也會向你顯示渲染這一幀過程當中系統正在執行的方法,因此你能夠調查引發那些UI jank的方法。

圖3:選擇有問題的幀,一個警告會出如今trace報告下面來標識問題。

       當你選擇一個渲染較慢的幀,你會在報告面板底部看到一個警告。圖3中顯示的警告喚起了該幀主要的問題,而該幀在ListView內回收和從新綁定時花費了太多時間。有一些連接指向trace中有關事件,他們解釋了更多關於這段時間內系統作了些什麼。

       爲了查看該工具在你的trace中發現的每個警告,以及該設備觸發每個警告的次數,請點擊窗口最右邊的「Alerts」標籤,如圖4所示。這個「Alerts」面板會幫你查看在這份trace中發生了什麼問題,以及引發UI jank的頻率。把這個面板當成一個bug列表去修復。一般,一個在某區域微小的改變或者改善可能消除你app中整個警告類型。

圖4:點擊右側的「Alert」按鈕將顯示「alter」標籤

       若是你看到在UI線程中作了太多的工做,你須要找出是哪一個方法消費了太多的CPU時間。有一種方法就是添加trace標記(查看「檢測你的app代碼」這一節)到那些你認爲有可能致使這些瓶頸的方法中,用來查看那些在systrace中出現的功能調用。若是你不肯定在UI線程中哪些方法可能致使瓶頸,使用Android Studio CPU profier 。你能夠生成trace日誌而且使用CPU Profiler來導入和檢測它們。  

  二、HTML報告鍵盤快捷鍵

     下面的表格列出了當瀏覽systrace HTML報告時可用的鍵盤快捷鍵。

按鍵 描述
W 放大trace時間軸。
S 縮小trace時間軸。
A 在時間軸上向左平移。
D 在時間軸上向右平移。
E 將trace時間軸置於當前鼠標的中心。
G 在當前選擇的任務的開始處顯示網格。
Shift + G 在當前選擇的任務的結尾處顯示網絡.
Right Arrow 在當前選擇的時間軸上選擇下一個事件(筆者注:當聚焦在frame 圓圈上時容易看到效果)。
Left Arrow 愛當前選擇的時間軸上選擇前一個事件。

 

4、檢測你的app代碼

       由於systrace僅僅只在系統級別給你顯示進程信息,因此在HTML報告中很難知道在給定的時間內你的app執行了哪些方法。在Android4.3(API level 18)已經更高的版本中,你能夠在你的代碼中使用Trace類來標記HTML報告中執行的事件。你沒有必要用systrace去檢測你的代碼來記錄trace,可是這樣作能夠幫助你看到你的app代碼中哪部分可能引發線程掛起或者UI jank。這種途徑有別於使用Debug類,Trace類簡單地添加標籤到systrace報告,可是Debug類經過.trace文件能幫助你檢測詳細的app CPU使用狀況。

       爲了生成包含你檢測trace事件的systrace HTML報告,你須要運行結合-a或者--app命令行運行systrace,並指明你的app的包名。

       下面的代碼實例向你展現了怎樣使用Trace類來標記方法的執行,包括在那個方法內的兩段嵌套的代碼塊:

 1 public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
 2     ...
 3     @Override
 4     public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
 5         Trace.beginSection("MyAdapter.onCreateViewHolder");
 6         MyViewHolder myViewHolder;
 7         try {
 8             myViewHolder = MyViewHolder.newInstance(parent);
 9         } finally {
10             // In 'try...catch' statements, always call endSection()
11             // in a 'finally' block to ensure it is invoked even when an exception
12             // is thrown.
13             Trace.endSection();
14         }
15         return myViewHolder;
16     }
17 
18    @Override
19     public void onBindViewHolder(MyViewHolder holder, int position) {
20         Trace.beginSection("MyAdapter.onBindViewHolder");
21         try {
22             try {
23                 Trace.beginSection("MyAdapter.queryDatabase");
24                 RowItem rowItem = queryDatabase(position);
25                 dataset.add(rowItem);
26             } finally {
27                 Trace.endSection();
28             }
29             holder.bind(dataset.get(position));
30         } finally {
31             Trace.endSection();
32         }
33     }
34 ...
35 }

 

★ 注意:當你調用beginSection(String)屢次,調用endSection()只結束最近一次調用的beginSection(String)。因此,對於嵌套的代碼,好比上面例子中的,你須要肯定你適當地匹配了一次beginSection()調用和一次endSection()。另外,你不能在一個線程中調用beginSection(),卻在另一個線程中結束它,你必須在相同的線程中調用endSection()。

 

結語

       到這裏,該篇文章就翻譯結束了,後面的文章中,筆者將根據本身的理解和實際操做,繼續對System Trace進行闡述。限於筆者的水平,若有翻譯不許確或不穩當的地方,望不吝賜教。

相關文章
相關標籤/搜索