appMethodOrder更新啦,廢棄dmtracedump解析,採用android studio官方源碼解析方案

背景:當項目代碼量很大的時候,或者你做爲一名新人要快速掌握代碼的時候,給函數打上log,來了解代碼執行邏輯,這種方式會顯然成本太大,要改動項目編譯運行,NO!太耗時;或者你想debug的方式來給你想關注的幾個函數,來了解代碼執行邏輯,NO!由於你確定會漏掉函數;也許你能夠執拗的給你寫的項目打滿log說這樣也行,可是你要知道你方法所調用的jdk的函數或者第三方aar或者jar再或者android sdk中的函數調用順序你怎麼辦,還能打log嗎?顯然不行吧,來~這個項目給讓可讓你以包名爲過濾點過濾你想要知道全部函數調用順序。html

項目地址:github.com/zjw-swun/Ap… 歡迎starjava

做者列表(排名按代碼貢獻時間順序):二精-霽雪清虹,xingstarx,大精-wing,pighead4u ,lijunjie,三精-虹貓,Harlbermysql

1. 效果奉上

圖片描述

動做簡介:首先點擊MainActivity的自定義MyTextView而後進入SecondActivity再點擊textview以後finish跳轉回MainActivity
下面是庫處理過所獲得的函數調用順序order.txt文件(我這裏屏蔽了jdk函數,第三方庫函數,以及android sdk中函數,換句話說我就保留了我本身包名中的函數順序)android

832 ent     67593 .....com.zjw.appmethodorder.MainActivity.onClick (Landroid/view/View;)V	MainActivity.java
832 ent     99956 ..........com.zjw.appmethodorder.MainActivity.onPause ()V	MainActivity.java
832 ent     99970 ...........com.zjw.appmethodorder.BaseActivity.onPause ()V	BaseActivity.java
832 ent    100472 ............com.zjw.appmethodorder.BaseActivity.baseOnPause ()V	BaseActivity.java
832 ent    128540 ........com.zjw.appmethodorder.SecondActivity.<init> ()V	SecondActivity.java
832 ent    128562 .........com.zjw.appmethodorder.BaseActivity.<init> ()V	BaseActivity.java
832 ent    213911 ........com.zjw.appmethodorder.SecondActivity.onCreate (Landroid/os/Bundle;)V	SecondActivity.java
832 ent    213928 .........com.zjw.appmethodorder.BaseActivity.onCreate (Landroid/os/Bundle;)V	BaseActivity.java
832 ent    258414 ..........com.zjw.appmethodorder.BaseActivity.baseOnCreate ()V	BaseActivity.java
832 ent   1440503 .........com.zjw.appmethodorder.SecondActivity.onResume ()V	SecondActivity.java
832 ent   1440563 ..........com.zjw.appmethodorder.BaseActivity.onResume ()V	BaseActivity.java
832 ent   1445675 ...........com.zjw.appmethodorder.BaseActivity.baseOnResume ()V	BaseActivity.java
832 ent   2954291 .................com.zjw.appmethodorder.MyTextView.onWindowVisibilityChanged (I)V	MyTextView.java
832 ent   3065664 ........com.zjw.appmethodorder.MainActivity.onStop ()V	MainActivity.java
832 ent   3065701 .........com.zjw.appmethodorder.BaseActivity.onStop ()V	BaseActivity.java
832 ent   3069155 ..........com.zjw.appmethodorder.BaseActivity.baseOnStop ()V	BaseActivity.java
832 ent   3139519 .......com.zjw.appmethodorder.SecondActivity.click (Landroid/view/View;)V	SecondActivity.java
832 ent   3146300 ........com.zjw.appmethodorder.SecondActivity.finish ()V	SecondActivity.java
832 ent   3183478 ..........com.zjw.appmethodorder.SecondActivity.onPause ()V	SecondActivity.java
832 ent   3183498 ...........com.zjw.appmethodorder.BaseActivity.onPause ()V	BaseActivity.java
832 ent   3183843 ............com.zjw.appmethodorder.BaseActivity.baseOnPause ()V	BaseActivity.java
832 ent   3209420 ........com.zjw.appmethodorder.MainActivity.<init> ()V	MainActivity.java
832 ent   3209438 .........com.zjw.appmethodorder.BaseActivity.<init> ()V	BaseActivity.java
832 ent   3283359 ........com.zjw.appmethodorder.MainActivity.onCreate (Landroid/os/Bundle;)V	MainActivity.java
832 ent   3283378 .........com.zjw.appmethodorder.BaseActivity.onCreate (Landroid/os/Bundle;)V	BaseActivity.java
832 ent   3330938 ..........com.zjw.appmethodorder.BaseActivity.baseOnCreate ()V	BaseActivity.java
832 ent   4363295 .....................com.zjw.appmethodorder.MyTextView.<init> (Landroid/content/Context;Landroid/util/AttributeSet;)V	MyTextView.java
832 ent   4436094 ..................com.zjw.appmethodorder.MyTextView.onFinishInflate ()V	MyTextView.java
832 ent   4449689 .........com.zjw.appmethodorder.MainActivity.initView ()V	MainActivity.java
832 ent   4539427 .........com.zjw.appmethodorder.MainActivity.onResume ()V	MainActivity.java
832 ent   4539467 ..........com.zjw.appmethodorder.BaseActivity.onResume ()V	BaseActivity.java
832 ent   4543597 ...........com.zjw.appmethodorder.BaseActivity.baseOnResume ()V	BaseActivity.java
832 ent   4917854 .................com.zjw.appmethodorder.MyTextView.onAttachedToWindow ()V	MyTextView.java
832 ent   4918658 .................com.zjw.appmethodorder.MyTextView.onWindowVisibilityChanged (I)V	MyTextView.java
832 ent   5090653 ...................................com.zjw.appmethodorder.MyTextView.onMeasure (II)V	MyTextView.java
832 ent   5355203 ..................................com.zjw.appmethodorder.MyTextView.onMeasure (II)V	MyTextView.java
832 ent   5456681 .......................................com.zjw.appmethodorder.MyTextView.onSizeChanged (IIII)V	MyTextView.java
832 ent   5467577 ....................................com.zjw.appmethodorder.MyTextView.onLayout (ZIIII)V	MyTextView.java
832 ent   5876623 ...........................................com.zjw.appmethodorder.MyTextView.onDraw (Landroid/graphics/Canvas;)V	MyTextView.java
832 ent   6121967 ........com.zjw.appmethodorder.SecondActivity.onStop ()V	SecondActivity.java
832 ent   6121986 .........com.zjw.appmethodorder.BaseActivity.onStop ()V	BaseActivity.java
832 ent   6123689 ..........com.zjw.appmethodorder.BaseActivity.baseOnStop ()V	BaseActivity.java
832 ent   6127522 ........com.zjw.appmethodorder.SecondActivity.onDestroy ()V	SecondActivity.java
832 ent   6127679 .........com.zjw.appmethodorder.BaseActivity.onDestroy ()V	BaseActivity.java
832 ent   6133301 ..........com.zjw.appmethodorder.BaseActivity.baseOnDestroy ()V	BaseActivity.java
複製代碼

2. 原理篇

廢棄dmtracedump解析,採用android studio官方源碼解析方案(官方android studio解析trace的移植版版本),核心代碼詳見com.android.tools.perflib.vmtrace.VmTraceParser類,相比以前的方案無需再配置dmtracedump環境變量,以及兼容android studio 3.1及其之後掐表生成的trace格式。git

3. 使用方法

3.1 生成trace文件的方式

生成trace文件的方式有2種操做,一種是在項目中使用代碼操做 即android.os.Debug.startMethodTracing();android.os.Debug.stopMethodTracing();,執行完stopMethodTracing將會在您手機app的sdcard下面生成.trace文件,該方式不區分版本,dumtracedump可解析
第二種方式是掐表生成trace文件
android studio 3.0以前版本操做以下
第一次點擊下圖時鐘icon表明開始掐表,而後回到您的app,進行您要跟蹤函數調用順序的操做,再次點擊下圖時鐘icon表明結束掐表 github

圖片描述
掐表結束後即會在captures目錄生成 com.zjw.appmethodorder_2017.03.25_21.41.trace文件,android studio會默認打開一個可視化窗口

圖片描述

android studio 3.0版本操做以下

點擊CPU 進入CPU面板,而後選擇Instrumented選項(Sampled和Instrumented區別在於,Sampled函數調用採樣率低生成的trace文件小,採樣率低會形成大部分函數調用順序漏記,Instrumented至關於無損採樣生成文件大),第一次點擊下圖紅色圓形icon表明開始掐表,而後回到您的app,進行您要跟蹤函數調用順序的操做,再次點擊下圖紅色圓形icon表明結束掐表, sql

圖片描述
圖片描述
結束掐表就會在 C:\Users\hasee\AppData\Local\Temp\cpu_trace.trace(本人是windows環境,使用windows系統能夠參照,使用Mac的同窗 cd /private/var/folders在folders 搜索cpu_trace.trace),存在cpu_trace.trace時會新建cpu_trace1.tracecpu_trace2.trace 以此類推

android studio 3.1開始,掐表默認實現改爲cpu profiler

詳見developer.android.google.cn/studio/prof…,若是掐表生成的trace文件能夠用文本編輯器打開看是否開頭帶有"slow"字樣,dmtracedump沒法解析,可是如今的小工具是基於最新android studio源碼實現,支持此種trace格式啦啦啦!。android studio 3.4掐表生成trace文件在cpu面板右鍵支持自定義路徑的export導出。數據庫

3.2 appMethodOrder小工具使用

appMethodOrder小工具 下載地址AppMethodOrderUtils.jar
appMethodOrder小工具 源碼地址AppMethodOrderUtils.zip appMethodOrder小工具改良自 github.com/Harlber/Met… 感謝Harlbergithub.com/Harlberwindows

好消息,如今小工具使用無需配置dmtracedump環境變量了!開箱即用!!!bash

將trace文件拖拽到小工具File Path左邊區域

圖片描述
package name處填入您須要過濾的目標包名,或者填入空串(空串將生成全部線程全部包名的函數調用順序)

圖片描述

如上圖所示,查詢結構存在四個tab,第一個threadID表明線程id,第二個threadName表明線程名,第三個usecs表明函數耗時(單位微秒,有時候耗時爲-1不要驚訝,是由於該次掐表恰好沒包括到其函數結束時機),第四個method表明函數名,(查詢結果是以時間排序的)

特別注意 這裏注意android studio 3.1之後掐表生成的trace 解析的時候 時間耗時有點小問題(官方代碼的問題),在一段時間內函數ent 給出的threadTime都是一致的,這裏須要小小的注意一下,因此3.1之後掐表要看耗時的朋友,建議仍是在studio面板看相對耗時,或者使用代碼方式生成trace文件。

4. 海量信息的處理手段

不難發現trace文件時間越長意味着記錄的信息也會愈來愈多,這時候單純以包名過濾其實知足不了需求,好比咱們想經過3個條件(例如 主線程+含zjw包名的 or android.view)來過濾出結果,如下將給出解決辦法。

appMethodOrder小工具會在該jar所在目錄生成appMethodOrderTrace.txt,以文本方式記錄查詢結果。 咱們能夠藉助數據庫這個工具使用查詢語句來幫助咱們過濾出有用的信息,可使用如下數據庫命令,把appMethodOrderTrace.txt內容導入到數據庫表中 //從text 導入數據到 mysql (如下語句在mysql中實驗是OK的)

truncate table app;
LOAD DATA LOCAL INFILE 'C:/Users/hasee/Desktop/appMethodOrderTrace.txt' INTO TABLE `app`;
複製代碼

圖片描述

app表結建立語句以下

CREATE TABLE `app` (
  `threadId` int(11) DEFAULT NULL,
  `threadName` varchar(255) DEFAULT NULL,
  `usecs` varchar(255) DEFAULT NULL,
  `method` varchar(255) DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
複製代碼

查詢語句示範 //查詢main線程中 自定義包下最耗時的操做(以毫秒爲單位,降序) SELECT threadName, usecs/1000, method FROM app WHERE app.threadName = "main" AND method like "%自定義包名%" ORDER BY app.usecs DESC

圖片描述

5. 計算得出的函數耗時不是準確的時間

根據官方文檔(developer.android.com/studio/prof…) Interpreted code runs more slowly when profiling is enabled. Don't try to generate absolute timings from the profiler results (such as, "function X takes 2.5 seconds to run"). The times are only useful in relation to other profile output, so you can see if changes have made the code faster or slower relative to a previous profiling run.所知(我也用了代碼在函數開頭結尾用System.nanoTime()時間相減,發現,生成trace的時候確實會拖慢因此函數的執行時間,比System.nanoTime()時間相減得出的時間差的比較多)。緣由是trace過程會總體拖慢JVM執行,所以函數耗時只是一個參考值,比較哪一個函數更耗時是能夠的。

相關文章
相關標籤/搜索