一 官方文檔翻譯html
官文地址:https://developer.android.com/studio/command-line/systracepython
systrace命令容許您在系統級別上收集和檢查全部運行在設備上的進程的耗時信息。它結合了來自Android內核的數據,例如CPU調度程序,磁盤活動和app線程,最後生成HTML報告,相似於圖1中所示。android
圖1:systrace HTML示例報告,程序默認抓取5秒內應用和系統的消耗。該報告突出顯示了systrace認爲的異常幀。web
此報告提供了在給定時間段內Android設備的系統進程的整體狀況。它還檢查捕獲的跟蹤信息以突出顯示它所發現的問題,例如在顯示動做或動畫時的UI jank,並提供有關如何修復它們的建議。可是, systrace工具不會收集有關app進程中代碼執行的信息。有關app正在執行的方法以及它使用的CPU資源的更多詳細信息,請使用Android Studio自帶的的CPU profiler,您還能夠生成跟蹤日誌並使用CPU profiler導入和檢查它們。json
本文檔說明如何從命令行經過systrace生成報告,查看生成的跟蹤文件,並使用它們分析和改進app用戶界面(UI)的性能。bootstrap
注意:在運行Android 9(API級別28)或更高版本的設備上,您還可使用名爲「系統跟蹤」的系統應用程序來記錄設備上的系統跟蹤。瀏覽器
要運行systrace,請完成如下步驟:app
1.從Android Studio下載並安裝最新的Android SDK工具。
2.安裝Python並配置環境變量。
3.使用USB調試將運行Android 4.3(API級別18)或更高版本的設備鏈接到開發系統。ionic
Systrace是Android SDK中自帶的一個命令工具,位於android-sdk/platform-tools/systrace/。ide
語法
要爲app生成HTML報告,您須要使用systrace的如下語法從命令行運行:
$ python systrace.py [options] [categories]
例如,如下命令調用systrace記錄設備活動並生成名爲mynewtrace.html的HTML報告。對於大多數設備來講,此類別列表是合理的默認列表。
$ python systrace.py -o mynewtrace.html sched freq idle am wm gfx view \
binder_driver hal dalvik camera input res
提示:若是要在跟蹤輸出中查看任務的名稱,則必須在命令參數中包含sched。
要查看已鏈接設備支持的類別列表,請運行如下命令:
$ python systrace.py --list-categories
若是未指定任何類別或選項,systrace默認會生成包含全部可用類別並使用默認設置的報告。可用的類別取決於您鏈接的設備。
全局選項
命令和命令選項
調查UI性能問題
systrace對於檢測app的UI性能特別有用,由於它能夠分析您的代碼和幀率,以識別問題所在並提出可能的解決方案或建議。首先,按如下步驟操做:
1.在鏈接的設備上運行您的應用。
2.systrace使用如下命令運行(此命令會跟蹤您的應用10秒鐘)
$ python systrace.py -t 10 [other-options] [categories]
3.在systrace運行的同時與您的應用互動。
4.在您定義的時間限制結束後(本次示例是10秒),systrace生成HTML報告。
5.使用Web瀏覽器打開HTML報告。
經過此報告,您能夠檢測設備CPU在記錄期間的使用狀況。
如下部分介紹瞭如何查閱報告中的信息以發現和修復UI性能問題。
查看幀和警告
如圖2所示,該報告列出了每一個進程沿時間軸的每一個渲染幀。綠色幀表示在16.6毫秒內渲染並保持每秒60幀穩定幀率的幀,黃色或紅色幀表渲染時間超過16.6毫秒的幀。
圖2:Systrace報告顯示放大耗時長的幀。
注意:在運行Android 5.0(API級別21)或更高版本的設備上,渲染幀的工做分配給了UI Thread和RenderThread。在之前的版本中,建立幀的全部工做都被UI Thread完成。
單擊幀會突出顯示它,並顯示有關係統完成該幀所作工做的其餘信息,包括警告。它還會向您顯示系統在渲染該幀時執行的方法,所以您能夠調查這些方法以獲取UI jank的緣由。
圖3.單擊異常幀,跟蹤報告下方會出現一個警告,用於識別問題。
選擇慢速幀後,您會在報告的底部窗格中看到警告。圖3中顯示的警告指出此幀的主要問題是在ListView回收和從新綁定中花費了太多時間 。點擊跟蹤中相關事件的連接,能夠更詳細地查看系統在此期間所執行的操做。
要查看Systrace工具在跟蹤中發現的每一個警告,以及設備觸發每一個警告的次數,請單擊窗口最右側的Alert按鈕,如圖4所示。警告面板可幫助您查看在跟蹤中發生的問題,以及它們對jank的貢獻頻率。能夠將警告面板視爲要修復的錯誤列表。一般一個區域的微小變化或改進能夠消除應用程序中的整個警告類別。
圖4:單擊右側的Alert按鈕顯示警告面板。
若是你發現UI線程作了不少的工做,你須要找出具體是哪些方法消耗了大多數CPU時間。一種方法是將跟蹤標記添加到您認爲致使這些瓶頸的方法中,而後在systrace中查看這些函數調用。若是您不肯定哪些方法可能致使UI線程出現瓶頸,請使用Android Studio的CPU Profiler。您可使用CPU Profiler生成跟蹤日誌並導入和檢查它們。
HTML報告的鍵盤快捷鍵
下表列出了查看systrace HTML報告時可用的鍵盤快捷鍵。
檢查應用代碼
由於systrace僅在系統級別顯示有關進程的信息,因此在HTML報告中很難了解你的APP在給定時間內具體執行的方法。在Android 4.3(API級別18)及更高版本中,您可使用代中的Trace類來標記HTML報告中的執行事件,您不須要經過檢查代碼來記錄跟蹤 。可是檢查代碼能夠幫助您瞭解app代碼的哪些部分可能會致使線程掛起或UI jank。這種方法與使用Debug類不一樣——Trace類只是向systrace報告添加標記,而Debug 類是經過生成.trace文件來幫助您詳細檢查app的CPU使用狀況。
要生成包含已檢測跟蹤事件的systrace HTML報告,您須要使用systrace的-a或--app選項運行命令行並指定app的包名稱。
下面的示例代碼演示如何使用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 { // In 'try...catch' statements, always call <code><a href="/reference/android/os/Trace.html#endSection()">endSection()</a></code> // in a 'finally' block to ensure it is invoked even when an exception // is thrown. Trace.endSection(); } return myViewHolder; }</p> <p>@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(); } } ... }
注意:當您屢次調用beginSection(String)方法時,每次會調用離beginSection(String)方法最近的endSection()方法。所以,對於嵌套調用,例如上面示例中的調用,您須要確保將每一個beginSection()方法的調用都正確匹配一個endSection()方法的調用。此外,在一個線程中你不能只調用beginSection()方法,您必須在同一線程中調用endSection()方法來結束它。
二 補充(摘自《大話APP測試2.0》)
Systrace是相似於Memory Monitor的一個縮小問題訪問、初步判斷問題的工具。但它也不是萬能的,須要TraceView的配合才能最終定位問題。
實戰:假設咱們如今面對着一個比較卡的列表界面,應該按照以下的步驟來執行。
1)保證當前環境下測試的應用版本都是正確和穩定的。
2)在終端開啓Systrace監聽命令(通常開10s就足夠了)。
3)在終端顯示當前正在蒐集Systrace時開始進行你認爲卡頓的那些操做,好比滾動ListView、切換Tab等。
4)看到終端顯示capture trace時意味着Systrace蒐集trace已經結束,此時等待html報告生成便可。
打開Systrace報告,若是看到SurfaceFlinger這一項的色條間隔很大而且很不規則,這說明咱們真實滾動列表時掉幀很厲害,從這個數據上面咱們能夠看出該ListView的功能體驗很很差,而且可以計算出掉幀率。
知道掉幀率以及的確卡頓後,咱們能夠經過「W」、「A」、「S」、「D」把結果放大,而後查看在掉幀的時間段內應用到底作了什麼,這樣就可以大概定位問題出在什麼地方了。
咱們來總結一下,經過Systrace獲得的信息有:
1)應用是否真的卡頓。
2)掉幀率是多少。
3)掉幀時應用到底在幹什麼。
4)單擊Systrace報告中的警告或者錯誤的標籤,看到對應的修改建議。
5)Kernel層CPU的使用狀況。
……
Systrace也並非全部的模塊或功能都支持的,那麼對於一些不支持但又要進行測試的功能應該怎麼辦?在Android4.3或者更高的版本中Android自己提供了Systrace類,能夠進行相關的引用從而最終可以在報告中查看到。以下是官方文檔中所提供的一段代碼,你們能夠參考。
public void ProcessPeople(){ Trace.beginSection("ProcessPeople"); try{ Trace.beginSection("Processing Jane"); try { //code for Jane task... }finish{ Trace.endSection();//ends "Processing Jane" } Trace.beginSection("Processing John"); try { //code for John task... }finish{ Trace.endSection();//ends "Processing John" } }finish{ Trace.endSection(); //ends "ProcessPeople" }
}
三 個人實戰
C:\Users\Administrator>adb devices # 查看設備 List of devices attached GSL7N16B10000581 device C:\Users\Administrator>D: # 進入D盤 D:\>cd software\Android\SDK\platform-tools\systrace # 進入Systrace目錄 D:\software\Android\SDK\platform-tools\systrace>dir # 查看該目錄:可看到有systrace.py文件 驅動器 D 中的卷是 軟件 卷的序列號是 A80B-3BC5 D:\software\Android\SDK\platform-tools\systrace 的目錄 2018\11\30 週五 14:25 <DIR> . 2018\11\30 週五 14:25 <DIR> .. 2018\11\22 週四 10:32 <DIR> catapult 2018\11\22 週四 10:32 11,738 NOTICE 2018\11\22 週四 10:32 1,456 systrace.py 2018\11\22 週四 10:32 41 UPSTREAM_REVISION 3 個文件 13,235 字節 3 個目錄 28,734,406,656 可用字節 D:\software\Android\SDK\platform-tools\systrace>python systrace.py -l #查看設備支持的類別 gfx - Graphics input - Input view - View System webview - WebView wm - Window Manager am - Activity Manager sm - Sync Manager audio - Audio video - Video camera - Camera hal - Hardware Modules app - Application res - Resource Loading dalvik - Dalvik VM rs - RenderScript bionic - Bionic C Library power - Power Management pm - Package Manager ss - System Server database - Database network - Network adb - ADB sched - CPU Scheduling freq - CPU Frequency idle - CPU Idle load - CPU Load memreclaim - Kernel Memory Reclaim binder_driver - Binder Kernel driver binder_lock - Binder global lock trace NOTE: more categories may be available with adb root D:\software\Android\SDK\platform-tools\systrace>python systrace.py -o mynewtrace.html -t 10 sched freq idle am wm gfx view binder_driver hal dalvik camera input res #在honor 8 Android 8.0設備上運行,報以下錯誤 Exception in thread Thread-11: Traceback (most recent call last): File "D:\software\Python27\lib\threading.py", line 801, in __bootstrap_inner self.run() File "D:\software\Python27\lib\threading.py", line 754, in run self.__target(*self.__args, **self.__kwargs) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\tracing_agents\atrace_agent.py", line 196, in _collect_and_preprocess trace_data = self._collect_trace_data() File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\tracing_agents\atrace_agent.py", line 256, in _collect_trace_data result = self._stop_collect_trace() File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\tracing_agents\atrace_agent.py", line 243, in _stop_collect_trace large_output=True, check_return=True, timeout=ADB_LARGE_OUTPUT_TIMEOUT) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\android\decorators.py", line 57, in timeout_retry_wrapper retry_if_func=retry_if_func) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\utils\timeout_retry.py", line 157, in Run error_log_func=error_log_func) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\utils\reraiser_thread.py", line 186, in JoinAll self._JoinAll(watcher, timeout) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\utils\reraiser_thread.py", line 151, in _JoinAll (len(alive_threads), len(self._threads))) CommandTimeoutError: Timed out waiting for 1 of 1 threads. Outputting Systrace results... Tracing complete, writing results Traceback (most recent call last): File "systrace.py", line 49, in <module> sys.exit(run_systrace.main()) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\run_systrace.py", line 201, in main main_impl(sys.argv) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\run_systrace.py", line 198, in main_impl controller.OutputSystraceResults(write_json=options.write_json) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\systrace_runner.py", line 69, in OutputSystraceResults self._out_filename) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\output_generator.py", line 99, in GenerateHTMLOutput html_file.write(_ConvertToHtmlString(result.raw_data)) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\output_generator.py", line 121, in _ConvertToHtmlString raise ValueError('Invalid trace result format for HTML output') ValueError: Invalid trace result format for HTML output D:\software\Android\SDK\platform-tools\systrace>python systrace.py -o mynewtrace.html -t 10 sched freq idle am wm gfx view hal dalvik camera input res # 在huawei M2-803L android 5.0.1 EMUI 3.1設備上運行報以下錯誤 Starting tracing (10 seconds) Tracing completed. Collecting output... CRITICAL:root:(TimeoutThread-1-for-Thread-11) Exception on ReadFile(YVF6R1741500 0417, /sys/kernel/debug/tracing/tracing_on, retries=3, timeout=30), attempt 1 of 4: AdbCommandFailedError("(device: YVF6R17415000417) adb pull /sys/kernel/debug /tracing/tracing_on 'c:\\users\\admini~1\\appdata\\local\\temp\\tmppdnptu\\tmp_R eadFileWithPull': failed with exit status 1 and output:\n- adb: error: remote ob ject '/sys/kernel/debug/tracing/tracing_on' does not exist\n",) CRITICAL:root:(TimeoutThread-2-for-Thread-11) Exception on ReadFile(YVF6R1741500 0417, /sys/kernel/debug/tracing/tracing_on, retries=3, timeout=30), attempt 2 of 4: AdbCommandFailedError("(device: YVF6R17415000417) adb pull /sys/kernel/debug /tracing/tracing_on 'c:\\users\\admini~1\\appdata\\local\\temp\\tmpepvljn\\tmp_R eadFileWithPull': failed with exit status 1 and output:\n- adb: error: remote ob ject '/sys/kernel/debug/tracing/tracing_on' does not exist\n",) CRITICAL:root:(TimeoutThread-3-for-Thread-11) Exception on ReadFile(YVF6R1741500 0417, /sys/kernel/debug/tracing/tracing_on, retries=3, timeout=30), attempt 3 of 4: AdbCommandFailedError("(device: YVF6R17415000417) adb pull /sys/kernel/debug /tracing/tracing_on 'c:\\users\\admini~1\\appdata\\local\\temp\\tmpiyef2y\\tmp_R eadFileWithPull': failed with exit status 1 and output:\n- adb: error: remote ob ject '/sys/kernel/debug/tracing/tracing_on' does not exist\n",) Exception in thread Thread-11: Traceback (most recent call last): File "D:\software\Python27\lib\threading.py", line 801, in __bootstrap_inner self.run() File "D:\software\Python27\lib\threading.py", line 754, in run self.__target(*self.__args, **self.__kwargs) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\tracing_agents\atrace_agent.py", line 196, in _collect_and_preprocess trace_data = self._collect_trace_data() File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\tracing_agents\atrace_agent.py", line 256, in _collect_trace_data result = self._stop_collect_trace() File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\tracing_agents\atrace_agent.py", line 247, in _stop_collect_trace if int(self._device_utils.ReadFile(is_trace_enabled_file)): File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\android\decorators.py", line 57, in timeout_retry_wrapper retry_if_func=retry_if_func) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\utils\timeout_retry.py", line 157, in Run error_log_func=error_log_func) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\utils\reraiser_thread.py", line 186, in JoinAll self._JoinAll(watcher, timeout) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\utils\reraiser_thread.py", line 158, in _JoinAll thread.ReraiseIfException() File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\utils\reraiser_thread.py", line 81, in run self._ret = self._func(*self._args, **self._kwargs) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\utils\timeout_retry.py", line 150, in <lambda> child_thread = reraiser_thread.ReraiserThread(lambda: func(*args, **kwargs), File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\android\decorators.py", line 47, in impl return f(*args, **kwargs) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\android\device_utils.py", line 1781, in ReadFile return self._ReadFileWithPull(device_path) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\android\device_utils.py", line 1733, in _ReadFileWithPull self.adb.Pull(device_path, host_temp_path) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\android\sdk\adb_wrapper.py", line 474, in Pull self._RunDeviceAdbCmd(cmd, timeout, retries) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\android\sdk\adb_wrapper.py", line 301, in _RunDeviceAdbCmd check_error=check_error) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\android\decorators.py", line 51, in timeout_retry_wrapper return impl() File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\android\decorators.py", line 47, in impl return f(*args, **kwargs) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\..\..\devil\devil\android\sdk\adb_wrapper.py", line 281, in _RunAdbCmd args, output, status, device_serial) AdbCommandFailedError: (device: YVF6R17415000417) adb pull /sys/kernel/debug/tra cing/tracing_on 'c:\users\admini~1\appdata\local\temp\tmp_ygea9\tmp_ReadFileWith Pull': failed with exit status 1 and output: - adb: error: remote object '/sys/kernel/debug/tracing/tracing_on' does not exis t Outputting Systrace results... Tracing complete, writing results Traceback (most recent call last): File "systrace.py", line 49, in <module> sys.exit(run_systrace.main()) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\run_systrace.py", line 201, in main main_impl(sys.argv) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\run_systrace.py", line 198, in main_impl controller.OutputSystraceResults(write_json=options.write_json) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\systrace_runner.py", line 69, in OutputSystraceResults self._out_filename) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\output_generator.py", line 99, in GenerateHTMLOutput html_file.write(_ConvertToHtmlString(result.raw_data)) File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra ce\output_generator.py", line 121, in _ConvertToHtmlString raise ValueError('Invalid trace result format for HTML output') ValueError: Invalid trace result format for HTML output
實戰總結:
1.測試發現目前運行Systrace命令只能使用Python2.7而不能使用Python3.X。
2.第一次運行Systrace命令時報錯:ImportError: No module named win32con。
解決方法:經過命令pip install pypiwin32或者python -m pip install pypiwin32 來安裝pypiwin32。
若是你沒有pip,請參考下面步驟:
下載(https://pypi.python.org/pypi/pip);
解壓;
安裝(Python setup.py install);
添加環境變量:D:\software\Python27\Scripts。
PS:個人電腦是裝了2個Python,一個Python2.7,一個Python3.5,結果執行pip install pypiwin32命令時把模塊安裝到了Python3.5裏,因而經過Python2.7執行Systrace命令時發現依然報錯。因此請確認你的pypiwin32確實安裝到了Python2.7裏(最好的辦法就是安裝前先卸載Python3.5)
3.解決了上面報錯後,發現又報錯:ValueError: Invalid trace result format for HTML output。查看stackoverflow後也沒找到合適的解決方案。