標籤:
轉載請標明出處:一片楓葉的專欄
上一篇文章中我們講解了android UI最佳化方面的知識。我們講解了android中的include、marge、ViewStub標籤,在使用這些標籤時可以簡化我們的布局檔案,最佳化組件繪製流程;講解了android中的過度繪製相關知識點,通過最佳化我們的App過度繪製可以提高App的UI繪製流程與效能;我們還講解了App中一些UI最佳化的小tips。更多關於android UI最佳化方面的知識可以參考我的:android產品研發(二十一)–>android中的UI最佳化
本文我們將講解android中的調試技巧。程式調試,是將編製的程式投入實際運行前,用手工或編譯器等方法進行測試,修正語法錯誤和邏輯錯誤的過程。這是保證電腦資訊系統正確性的必不可少的步驟。在android開發過程中熟練的使用調試技巧是一個很重要的方面。android的調試技巧包括熟練使用android中的日誌API,自訂android日誌架構,通過gradle配置調試日誌,android studio的調試技巧等等。通過對本文的學習我們能夠對android中調試技巧有一個大概的瞭解。
android中的列印API:
我們首先來看一下android中提供的列印日誌API:
android.util.Log.java
這個類比較常用的列印日誌的方法有5個,這5個方法都會把日誌列印到AndroidMonitor中,android中日誌分為五個層級:
Log.v(tag,message); //verbose模式,列印最詳細的日誌
Log.d(tag,message); //debug層級的日誌
Log.i(tag,message); //info層級的日誌
Log.w(tag,message); //warn層級的日誌
Log.e(tag,message); //error層級的日誌
其中tag和message分別是兩個String值.從android開發協助文檔中來看,tag和message的定義分別是:
tag:Used to identify the source of a log message. It usually identifies the class or activity where the log call occurs.
msg:The message you would like logged.
可看出tag用來標記log訊息的源頭的。而message則是這條log的內容.
Log demo代碼:
/** * 按鈕點擊事件,列印各個層級的日誌 */button6.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.v(TAG, "this is a verbose log!!!"); Log.d(TAG, "this is a debug log!!!"); Log.i(TAG, "this is a info log!!!"); Log.w(TAG, "this is a warning log!!!"); Log.e(TAG, "this is a error log!!!"); } });
好吧,我們點擊按鈕,看一下AndroidMonitor中的列印結果:
07-17 19:22:16.202 7530-7530/uuch.com.android_activityanim V/MainActivity: this is a verbose log!!!07-17 19:22:16.202 7530-7530/uuch.com.android_activityanim D/MainActivity: this is a debug log!!!07-17 19:22:16.202 7530-7530/uuch.com.android_activityanim I/MainActivity: this is a info log!!!07-17 19:22:16.202 7530-7530/uuch.com.android_activityanim W/MainActivity: this is a warning log!!!07-17 19:22:16.203 7530-7530/uuch.com.android_activityanim E/MainActivity: this is a error log!!!
通過這種android自身Log API列印日誌的方式,是最常見的一種列印日誌的,調試代碼的方式,基本上所有的項目中你可能都會遇到這種日誌代碼,前面的一篇文章中我也分析了Log日誌的部分源碼,具體可參考我的:android源碼解析之(六)–>Log
但是呢你會發現這時候列印的日誌格式比較簡陋,比如出現異常的時候我們想快速定位到代碼在哪,這時候就比艱難了,所以下面我們講一下自訂日誌架構。
自訂android列印架構MLog:
前面我們發現使用Android原生的Log API列印的日誌格式比較簡陋,那麼可不可以定製化的顯示一些友好型的日誌資訊呢?答案是肯定的,在前面的文章中我介紹了一個自訂的日誌架構MLog,可參考我的:github項目解析(五)–>android日誌架構
關於MLog架構的使用方式,實現過程等已在文章中做過簡單的介紹,這裡就看一下其列印的日誌格式:
自訂按鈕點擊事件:
/** * 傳入為true,則表示執行列印操作,否則不顯示日誌 */MLog.init(true);
盡量可以在Application的onCreate方法中執行,這是App的進程起始方法。
/** * 自訂按鈕的點擊事件 */button6.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MLog.v(TAG, "this is a verbose log!!!"); MLog.d(TAG, "this is a debug log!!!"); MLog.i(TAG, "this is a info log!!!"); MLog.w(TAG, "this is a warning log!!!"); MLog.e(TAG, "this is a error log!!!"); } });
在AndroidMoitor中列印的日誌格式和內容:
這樣我們在點擊日誌資訊的時候就能夠跳轉到這條日誌的代碼列印位置,是不是很方便?而且如果覺得日誌格式不是很好的話,還可以定製化展示奧。
比如:
怎麼樣?是不是很好看了?
具體如何?自訂Log架構以及自訂實現Log的顯示樣式可以參考我的:github項目解析(五)–>android日誌架構
大多時候我們的App都有測試環境和正式環境兩種環境的,當切換環境的時候要求我們在測試環境列印日誌,則正式環境屏蔽日誌,通過代碼也可以實現,但是比較麻煩,有沒有一個比較簡單的方法呢?答案是肯定的,可以通過配置gradle的方式配置在測試環境中列印日誌,在正式環境中屏蔽日誌列印操作。
gradle中配置正式測試列印架構:
我們知道在android開發過程中為了調試代碼經常在代碼中添加一些日誌資訊,但是正式環境是不需要這些日誌資訊的,而且過得日誌列印操作也會對App的效能有影響。
一個比較好的辦法就是在App的測試環境中列印日誌資訊,在正式環境中屏蔽日誌資訊,那麼如何?呢?通過代碼嗎?通過代碼也是可以實現的,但是這樣顯得太原始了,其實android studio的gradle外掛程式已經提供了這樣的功能。
那麼如何通過gradle配置日誌列印資訊呢?
buildTypes { debug { // 顯示Log buildConfigField "boolean", "LOG_DEBUG", "true" //混淆 minifyEnabled false //Zipalign最佳化 zipAlignEnabled true // 移除無用的resource檔案 shrinkResources true //載入預設混淆設定檔 proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘ //簽名 signingConfig signingConfigs.debug } release { // 不顯示Log buildConfigField "boolean", "LOG_DEBUG", "false" //混淆 minifyEnabled true //Zipalign最佳化 zipAlignEnabled true // 移除無用的resource檔案 shrinkResources true //載入預設混淆設定檔 proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘ //簽名 signingConfig signingConfigs.relealse } }
在android studio的module的gradle設定檔中,在buildTypes節點下可以配置自訂參數,這裡我們在debug版本中定義LOG_DEBUG為true,在release版本中定義LOG_DEBUG為false。這樣在編譯的時候就會在gradle的編譯類BuildConfig中產生成員變數:
LOG_DEBUG
若是正式環境則LOG_DEBUG的值為false
若是測試環境則LOG_DEBUG的值為true
所以這時候可以通過LOG_DEBUG變數的值控制日誌是否列印。
/** * 在Application的onCreate方法中初始化MLog日誌架構 * 並根據apk環境判斷是否顯示日誌資訊 */if (BuildConfig.LOG_DEBUG == true) { MLog.init(true);} else { MLog.init(false);}
我們實現的MLog架構的init方法
這樣我們就實現了在測試環境列印日誌,在正式環境中屏蔽日誌的操作。
android studio的調試技巧:
寫代碼的過程中不可避免有Bug,通常情況下除了日誌最直接的調試手段就是debug;那麼你的調試技術停留在哪一階段呢?僅僅是下個斷點逐步執行嗎?你是否知道求值調試,條件斷點,日誌斷點,方法斷點,異常斷點等調試技巧嗎?下面我們將介紹一下android studio中的調試技巧。
調試基礎
一般來說我們有兩種辦法調試一個debuggable的apk;
一般比較常使用的debug方式是attach debugger to android process:
在執行按鈕右側兩個的帶有小蟲子的按鈕其實就是Attach Debugger to android process按鈕。
我們可以在啟動apk之後,直接下斷點,然後attach process到指定進程,條件觸發之後就可以直接進入偵錯模式。
斷點調試
斷點調試是最基本操作,基恩的斷點調試有以下的幾個常用的調試命令:
F5跳轉內部執行
F6跳轉下一步
F8跳轉到下一個斷點
如何添加斷點?
直接在android studio中的java原始碼左側,想調試某一行代碼的話,直接單擊若左側出現了一個小紅圈,則說明斷點已經添加好了:
當代碼處於debug模式,並且執行到此處的時候就會卡住在這裡。
執行斷點調試
執行attach debugger to android process,當代碼執行到含有斷點的時候就可以將程式卡到斷點的代碼了:
這時候我們可以看到在該行代碼中可以看到相應的局部變數值,執行F6走到下一步,執行F8,調試到下一個斷點。
添加觀察變數
在偵錯模式下,選擇變數,並右擊:
這時候選擇Add to watches,就可以將變數添加到觀察列表了。
運算式調試:Evaluate Expression
這個調試功能非常的實用,也是我最喜歡的功能,使用ctrl + u快速鍵可以彈窗運算式調試彈窗:
這個功能非常實用,可以在斷點處直接進入一個求值環境,在這裡你可以執行任何你感興趣的運算式可以在運算式調試彈窗中寫任何java運算式,比如:
其他的比如在斷點處有一個對象object,如果你要查看它的某個屬性很簡單,在Debug視窗就能看到,但是如果你想要執行它的某個方法看看結果是什麼呢?藉助這個可以實現。當然它的功能遠不止這麼多,相當於直接進入了一個 REPL環境,非常實用。
條件斷點
假設你的斷點在一個列表的迴圈裡面,可是你只對這個列表的某一個元素感興趣,只想在遇到這個元素的時候才斷下來;你是一直人肉 F9 直到滿足條件嗎?條件斷點就是滿足這種需求的,顧名思義,在特定條件下的斷點。使用起來也非常簡單,在你的斷點上滑鼠右鍵會出現一個小視窗,寫上條件即可。
其他斷點調試方式
除了這裡的求值斷點,條件斷點,還有日誌斷點,異常斷點,方法斷點等,具體的可自行google哈。
總結:
android預設提供了Log API實現對日誌的列印功能;
可以實現自訂日誌架構,定製化顯示日誌樣式,定製化配置是否顯示日誌等,可參考:android日誌架構
可以通過配置gradle,讓測試環境中顯示日誌資訊,在正式環境中不顯示日誌資訊;
android studio提供了斷點調試功能,包含了求值調試,條件斷點,日誌斷點,方法斷點,異常斷點等等;
另外對產品研發技術,技巧,實踐方面感興趣的同學可以參考我的:
android產品研發(十二)–>App長串連實現
android產品研發(十三)–>App輪訓操作
android產品研發(十四)–>App升級與更新
android產品研發(十五)–>記憶體對象序列化
android產品研發(十六)–>開發人員選項
android產品研發(十七)–>Hybrid開發
android產品研發(十八)–>webview問題集錦
android產品研發(十九)–>android studio中的單元測試
android產品研發(二十)–>代碼Review
android產品研發(二十一)–>android中的UI最佳化
本文以同步至github中:https://github.com/yipianfengye/androidProject,歡迎star和follow
android產品研發(二十二)-->android實用調試技巧