編輯:關於Android編程
上一篇文章中我們講解了android UI優化方面的知識。我們講解了android中的include、marge、ViewStub標簽,在使用這些標簽時可以簡化我們的布局文件,優化組件繪制流程;講解了android中的過度繪制相關知識點,通過優化我們的App過度繪制可以提高App的UI繪制流程與性能;我們還講解了App中一些UI優化的小tips。
本文我們將講解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 API例子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框架的使用方式,實現過程等已在文章中做過簡單的介紹,這裡就看一下其打印的日志格式:
自定義按鈕點擊事件:
在Application中初始化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中打印的日志格式和內容:
這樣我們在點擊日志信息的時候就能夠跳轉到這條日志的代碼打印位置,是不是很方便?而且如果覺得日志格式不是很好的話,還可以定制化展示奧。
比如:
vcXk1sPU2rLiytS7t76z1tC08tOhyNXWvqOs1NrV/cq9u7e+s9bQxsGxzsjV1r608tOhstnX96GjPC9wPg0KPHA+PHN0cm9uZz5ncmFkbGXW0MXk1sPV/cq9suLK1LTy06G/8rzco7o8L3N0cm9uZz48L3A+DQo8cD7O0sPH1qq1wNTaYW5kcm9pZL+qt6K5/bPM1tDOqsHLtffK1LT6wuu+rbOj1Nq0+sLr1tDM7bzT0rvQqcjV1r7Qxc+io6y1q8rH1f3Kvbu3vrPKx7K70OjSqtXi0KnI1da+0MXPorXEo6y2+MfSuf21w8jV1r608tOhstnX99Kyu+G21EFwcLXE0NTE3NPQ07DP7KGjPC9wPg0KPHA+0ru49rHIvc+6w7XEsOy3qL7NysfU2kFwcLXEsuLK1Lu3vrPW0LTy06HI1da+0MXPoqOs1NrV/cq9u7e+s9bQxsGxzsjV1r7Qxc+io6zEx8O0yOe6zsq1z9bE2KO/zai5/bT6wuvDtKO/zai5/bT6wuvSssrHv8nS1Mq1z9a1xKOstavKx9Xi0fnP1LXDzKvUrcq8wcujrMbkyrVhbmRyb2lkIHN0dWRpb7XEZ3JhZGxlsuW8/tLRvq3M4bmpwcvV4tH5tcS5psTcoaM8L3A+DQo8cD7Ex8O0yOe6zs2ouf1ncmFkbGXF5NbDyNXWvrTy06HQxc+ixNijvzwvcD4NCjxwcmUgY2xhc3M9"brush:java;">
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方法
若傳入的值為true,則表示執行日志打印操作,也就是可以顯示日志信息。
若傳入的值為false,則表示不執行日志打印操作,也就是不顯示日志信息。
這樣我們就實現了在測試環境打印日志,在正式環境中屏蔽日志的操作。
android studio的調試技巧:
寫代碼的過程中不可避免有Bug,通常情況下除了日志最直接的調試手段就是debug;那麼你的調試技術停留在哪一階段呢?僅僅是下個斷點單步執行嗎?你是否知道求值調試,條件斷點,日志斷點,方法斷點,異常斷點等調試技巧麼?下面我們將介紹一下android studio中的調試技巧。
調試基礎
一般來說我們有兩種辦法調試一個debuggable的apk;
設置好斷點,然後用debug模式編譯安裝這個app;
執行attach debugger to android process,即將debug進程添加到當前進程中。
一般比較常使用的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實現對日志的打印功能;
可以實現自定義日志框架,定制化顯示日志樣式,定制化配置是否顯示日志等
可以通過配置gradle,讓測試環境中顯示日志信息,在正式環境中不顯示日志信息;
android studio提供了斷點調試功能,包含了求值調試,條件斷點,日志斷點,方法斷點,異常斷點等等;
本文以同步至github中:https://github.com/yipianfengye/androidProject,歡迎star和follow
ContextMenu介紹: 如果一個View注冊了上下文菜單,那麼當長按該View時便會彈出一個浮動菜單,來供選擇下一步操作。 實現這個功能需要調用setOnCrea
1、用於沒有一點提示的情況:依次打開eclipse上面的windows ——preferences ——java ——editor —— content assist ,
Android提供了兩種事件處理的方式:基於回調的事件處理 和 基於監聽的事件處理。 我們來說的容易理解一點:(1)基於回調的事件處理就是繼承GUI組件,並重寫
有段時間沒寫博客了,可能寫博客的時間都用去把妹了吧。說到把妹,偶爾也會在無意間了解一些把妹的技巧,比如雲擒故縱啊什麼的。可能這些技巧前期會有一定的作用,可能會讓妹子對你產