———————————————————————
『很多童鞋說我的代碼運作後,點選home或者back後會程式異常,如果你也這樣遇到過,那麼你肯定沒有仔細讀完himi的博文,第十九篇himi專門寫了關于這些錯誤的原因和解決方法,這裡我在部落格都補充說明下,省的童鞋們總疑惑這一塊;請點選下面聯系進入閱讀:
——————————————————————-
由于本人現在在一家專職做網遊的公司,是以現在需要使用一些方法對現營運的網遊代碼進行精簡和優化,那麼就要使用到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”);
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卡中寫入了資料,是以需要聲明一條權限。這裡必須注意哦!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.himi"
android:versioncode="1"
android:versionname="1.0"&gt;
&lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt;
&lt;activity android:name=".mainactivity"
android:label="@string/app_name"&gt;
&lt;intent-filter&gt;
&lt;action android:name="android.intent.action.main" /&gt;
&lt;category android:name="android.intent.category.launcher" /&gt;
&lt;/intent-filter&gt;
&lt;/activity&gt;
&lt;/application&gt;
&lt;uses-permission android:name="android.permission.write_external_storage"&gt;&lt;/uses-permission&gt;
&lt;uses-sdk android:minsdkversion="4" /&gt;
&lt;/manifest&gt;
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函數的代碼如下:
/**
* @author himi
* @param canvas
*/
public void hot(canvas canvas) {
for (int i = 1; i &lt; 100; i++) {
bitmap bmp = bitmapfactory.decoderesource(getresources(),
r.drawable.icon);
canvas.drawbitmap(bmp, i += 2, i += 2, paint);
}
}
很明顯我在故意消耗記憶體和時間。
那麼,在traceview的右半部統計字段中:
exclusive: 同級函數本身運作的時間
inclusive 就是說除統計函數本身運作的時間外再加上調用子函數所運作的時間
name:列出的是所有的調用項,前面的數字是編号,展開可以看到有的有parent 和children子項,就是指被調用和調用。
incl: inclusive時間占總時間的白分比
excl: 執行占總時間的白分比。
calls+recur calls/total: 調用和重複調用的次數
time/call: 總的時間。(ms)
是以traceview是個非常好的程式監視工具,可以幫助找出程式運作緩慢時的函數,讓我們的代碼不斷完善和改進!