李華明Himi 原創,轉載務必在明顯處註明:
不少童鞋說個人代碼運行後,點擊home或者back後會程序異常,若是你也這樣遇到過,那麼你確定沒有仔細讀完Himi的博文,第十九篇Himi專門寫了關於這些錯誤的緣由和解決方法,這裏我在博客都補充說明下,省的童鞋們總疑惑這一塊;請點擊下面聯繫進入閱讀:css
【Android遊戲開發十九】(必看篇)SurfaceView運行機制詳解—剖析Back與Home按鍵及切入後臺等異常處理!html
因爲本人如今在一家專職作網遊的公司,因此如今須要使用一些方法對現運營的網遊代碼進行精簡和優化,那麼就要使用到Android sdk中提供的一款很好的檢視工具—Android TraceView、下面先給出對此的解釋:而後講解實現的詳細步驟和須要特別注意的一點!java
什麼是TraceView?先看下百度出來的解釋吧:android
Traceview是android平臺配備一個很好的性能分析的工具。它能夠經過圖形化的方式讓咱們瞭解咱們要跟蹤的程序的性能,而且能具體到method。canvas
關於Traceview的使用windows
首先,必須在程序當中加入代碼,以便生成trace文件,有了這個trace文件才能夠將其轉化爲圖形。api
要添加的代碼以下:app
Java代碼eclipse
// start tracing to "/sdcard/yourActivityTrace.trace"ide
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卡中寫入了數據,因此須要聲明一條權限。這裏必須注意哦!
<?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>
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 < 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是個很是好的程序監視工具,能夠幫助找出程序運行緩慢時的函數,讓咱們的代碼不斷完善和改進!
(歡迎你們訂閱本博客,由於咱的更新速度但是很快的~娃哈哈)