由於本人現在在一家專職做網遊的公司,所以現在需要使用一些方法對現運營的網遊代碼進行精簡和最佳化,那麼就要使用到Android sdk中提供的一款很好的檢視工具—Android TraceView、下面先給出對此的解釋:然後講解實現的詳細步驟和需要特別注意的一點!
什麼是TraceView?先看下百度出來的解釋吧:
Traceview是android平台配備一個很好的效能分析的工具。它可以通過圖形化的方式讓我們瞭解我們要跟蹤的程式的效能,並且能具體到method。
關於Traceview的使用
首先,必須在程式當中加入代碼,以便產生trace檔案,有了這個trace檔案才可以將其轉化為圖形。
要添加的代碼如下:
Java代碼
// start tracing to "/sdcard/yourActivityTrace.trace"
Debug.startMethodTracing("yourActivityTrace");
// ... // stop tracing Debug.stopMethodTracing();
// start tracing to "/sdcard/yourActivityTrace.trace" Debug.startMethodTracing("yourActivityTrace");
// ... // stop tracing Debug.stopMethodTracing();
Google Dev Guide當中說可以在activity的onCreate()中添加Debug.startMethodTracing(), 而在onDestroy()中添加Debug.stopMethodTracing(),但是在實際的測試時發現這種方式其實並不好用,因為通常情況下我們的activity的onDestroy()是由系統決定何時調用的,因此可能等了很長時間都不會得到這個trace檔案。因此決定在onStop()中來調用Debug.stopMethodTracing()。這樣當我們切換到其它activity或者點擊home鍵的時候onStop()就會被調用,我們也就可以得到完整的trace
file。
在運行程式之前,首先要保證我們的AVD是一個帶有SD card的AVD,這樣才能使trace檔案儲存到/sdcard/...當中。運行後可以任意做一些操作,然後點擊home鍵。這是通過DDMS file explore就可以看到/sdcard/目錄下有一個trace檔案,現在把這個檔案copy到電腦上指定的目錄,假設是C:/tracefile 目錄下。
可以通過命令列來執行traceview,進入tools目錄後,執行
traceview C:/tracefile/yourActivityTrace.trace
之後就可以看到圖形了,接下來就是按照Google Dev Guide中的解釋去分析圖形就OK了。
下面來看如何?以及需要注意的地方:
實現的步驟分為三步:1.必須先在我們的模擬器中建立sdCard ;2.將我們的調試代碼嵌入工程;3.利用TraceView來觀察和分析代碼情況;
1.對於建立模擬器的sdCard這裡寫出兩種方式:
第一種:我們在eclipse中建立avd的時候的時候 在選擇api下面有個 Sd Card 的選項,第一項填入建立sdcard的大小即可。
第二種:cmd 命令! 開啟cmd 並且cd 到android sdk tool 路徑下;(或者在環境變數Path中將sdk tool路徑配置上,然後重新開啟cmd)
使用 mksdcard -l mycard 1024M F:/mysdcard.img 建立了一個1G的sdcard;
使用 emulator -avd my_android -sdcard F:/mysdcard.img 啟用sdcard!
最後在eclipse Preferences-->Android-->Launch加入 -sdcard F:/mysdcard.img (此步驟就是在第一種建立方式中添加sdcard的支援)
備忘1:
如果sdcard分配的空間太小,則程式追蹤檔案就一直記錄到sd儲蓄卡容量慢為止,所以調試前,要為程式產生一個適當的SD儲存卡也較為重要,因為程式已耗用時間越長,這個追蹤檔案也就越大。
備忘2;
(如果第二種建立方式中的第二部啟用出現 emulator: ERROR: the user data image is used by another emulator. aborting,請關閉模擬器,或者進入目錄: /Documents and Settings / 使用者 / .android /的AVD / *裝置* / (比如我的目錄是:C:/Documents and Settings/Administrator/.android/avd/android2.0.avd)
然後刪去以.lock結尾的檔案夾就行(我簡單解釋下為什麼要刪除這些檔案呢,其實.lock是加鎖,如果程式崩潰等原因導致無法清除這些以.lock結尾的檔案夾,就會出現這個問題,也就是這個avd的鎖沒有被釋放,導致avd manager以為這個avd正在使用當中。))
2.將我們的調試代碼嵌入工程
正如我們百度到的說明一樣,在程式啟動並執行開端加上 Debug.startMethodTracing("yourActivityTrace"); 然後在onPause()中調用Debug.stopMethodTracing(); 為什麼要將結束寫在onPause()中而不寫在onStop(),那麼如果你去看api的話,你會看到,Api中介紹onPause()會在你返回和點擊home按鍵後觸發,而onStop()一般是由系統來觸發,當該程式處於背景時候,而且當記憶體緊張的時候,可能會調用,但是可能永遠不會調用到!
備忘:要記住當把調試代碼加入項目中以後不要立即運行項目,而是必須在AndroidMainfest.xml中定義一條"寫入SD卡的許可權"那麼添加許可權的代碼如下:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
因為咱們的調試代碼會在SD卡中產生一個追蹤檔案,也就是往SD卡中寫入了資料,所以需要聲明一條許可權。這裡必須注意哦!
[java:showcolumns]
view plaincopyprint?·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.himi"
- android:versionCode="1"
- android:versionName="1.0">
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name=".MainActivity"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
- <uses-sdk android:minSdkVersion="4" />
- </manifest>
<?xml version="1.0" encoding="utf-8"?><br /><manifest xmlns:android="http://schemas.android.com/apk/res/android"<br /> package="com.himi"<br /> android:versionCode="1"<br /> android:versionName="1.0"><br /> <application android:icon="@drawable/icon" android:label="@string/app_name"><br /> <activity android:name=".MainActivity"<br /> android:label="@string/app_name"><br /> <intent-filter><br /> <action android:name="android.intent.action.MAIN" /><br /> <category android:name="android.intent.category.LAUNCHER" /><br /> </intent-filter><br /> </activity><br /> </application><br /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission><br /> <uses-sdk android:minSdkVersion="4" /><br /></manifest>
3.運行項目並且退出項目從而得到的追蹤檔案,利用TraceView來進行分析代碼健全狀態:
打當正常運行了項目並且點擊返回或者home按鍵就會在 sdcard中產生一個.trace的檔案。sdcard 目錄 在eclipse下,點擊:
windows-show view-other-android-File explorer
右上方的兩個箭頭,第一個表示從模擬器sdcard匯出檔案,第二個表示從PC上匯入檔案到sdcard中、“—”代表刪除 .....
然後我們通過cmd來運行產生的追蹤檔案 traceview C:/name 追蹤檔案所在的路徑放在C盤,放在C盤以外別的盤的話我這裡是無法正常開啟traceview的不知道什麼原因。 name 表示產生的.trace檔案,cmd的時候不需要輸入“.trace”尾碼 ;然後會出現TraceView的分析視窗;
【cmd 命令! 開啟cmd 並且cd 到android sdk tools 路徑下;(或者在環境變數Path中將sdk tool路徑配置上,然後重新開啟cmd)】
注意1:如果出現一片這種記憶體溢出的問題;
解決方案:到SDK 下的tools 下 找到 traceview.bat 檔案,滑鼠右鍵-編輯(或者記事本開啟),最後一行替換成這樣:
call java -Xms128m -Xmx512m -Djava.ext.dirs=%javaextdirs% -jar %jarpath% %*
注意2:如果出現路徑不對的問題:
例如:我的 himi.trace 放在了C盤,那麼我的cmd命令是: traceview c:/himi 然後斷行符號!
但是這裡要小心,因為 /h 這樣可能被認為是逸出字元!!!為了避免可以儘可能不要使用h,n,r,t,等等成為名字的頭字母,當然還有一種就可以完全避免這種問題,例如還是我的C盤 himi.trace 檔案,可以寫cmd命令的時候寫成: traceview c://himi 嘿嘿~要注意細節。
下面是運行起來的TranceView:
最右上方表示運行程式總共用了多少時間,從traceview畫面中我們看到有各種顏色,每種顏色代表不同的函數和步驟,那麼同一顏色的地區越大,就代表這個步驟已耗用時間越長,或者看到下面的統計表,明顯可以看出除了序列 0 1 是系統函數外,2. 3.函數 佔用的時間比較長,那麼序列4是個自訂的函數名為 “hot”這個佔用了幾乎與主線程 主draw的時間一樣了,那麼肯定有問題。當然其實這個方法是我故意寫的,就是為了來示範traceview。這個hot函數的代碼如下:
[java:showcolumns]
view plaincopyprint?·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
- /**
- * @author Himi
- * @param canvas
- */
- public void hot(Canvas canvas) {
- for (int i = 1; i < 100; i++) {
- Bitmap bmp = BitmapFactory.decodeResource(getResources(),
- R.drawable.icon);
- canvas.drawBitmap(bmp, i += 2, i += 2, paint);
- }
- }
/**<br /> * @author Himi<br /> * @param canvas<br /> */<br />public void hot(Canvas canvas) {<br />for (int i = 1; i < 100; i++) {<br />Bitmap bmp = BitmapFactory.decodeResource(getResources(),<br />R.drawable.icon);<br />canvas.drawBitmap(bmp, i += 2, i += 2, paint);<br />}<br />}
很明顯我在故意消耗記憶體和時間。
那麼,在traceview的右半部統計欄位中:
Exclusive: 同級函數本身啟動並執行時間
Inclusive 就是說除統計函數本身啟動並執行時間外再加上調用子函數所啟動並執行時間
Name:列出的是所有的調用項,前面的數字是編號,展開可以看到有的有Parent 和Children子項,就是指被調用和調用。
Incl: inclusive時間佔總時間的白分比
Excl: 執行佔總時間的白分比。
Calls+Recur Calls/Total: 調用和重複調用的次數
Time/Call: 總的時間。(ms)
所以traceview是個非常好的程式監視工具,可以協助找出程式運行緩慢時的函數,讓我們的代碼不斷完善和改進!
原文轉自:http://blog.csdn.net/xiaominghimi/article/details/6105212