你所不知道的Android Studio调试技巧
原文鏈接:簡(jiǎn)書(shū)@涅槃1992 http://www.jianshu.com/p/011eb88f4e0d
Android Studio目前已經(jīng)成為開(kāi)發(fā)Android的主要工具,用熟了可謂相當(dāng)順手。作為開(kāi)發(fā)者,調(diào)試并發(fā)現(xiàn)bug,進(jìn)而解決,可是我們的看家本領(lǐng)。正所謂,工欲善其事必先利其器,和其他開(kāi)發(fā)工具一樣,如Eclipse、Idea,Android Studio也為我們提供了強(qiáng)大的調(diào)試技巧,今天我們就來(lái)看看Android Studio中有關(guān)調(diào)試的技巧。
首先,來(lái)看看Android studio中為我們提供的調(diào)試面板(標(biāo)準(zhǔn)情況下):
點(diǎn)擊右上角Restore ‘Threads’View可先展示目前相關(guān)的線(xiàn)程信息:
android studio大體為我們提供了7個(gè)功能區(qū):
- 單步調(diào)試區(qū)
- 斷點(diǎn)管理區(qū)
- 求值表達(dá)式
- 線(xiàn)程幀棧區(qū)
- 對(duì)象變量區(qū)
- 變量觀察區(qū)
下面我們分別對(duì)這七個(gè)區(qū)域進(jìn)行介紹。
單步調(diào)試區(qū)
該區(qū)提供了調(diào)試的主要操作,和你所熟知的一樣的,主要有:Step over、step into、force step into、step out、drop frame。
Show Execution Point
點(diǎn)擊該按鈕,光標(biāo)將定位到當(dāng)前正在調(diào)試的位置.
Step Over
單步跳過(guò),點(diǎn)擊該按鈕將導(dǎo)致程序向下執(zhí)行一行。如果當(dāng)前行是一個(gè)方法調(diào)用,此行調(diào)用的方法被執(zhí)行完畢后再到下一行。比如當(dāng)前代碼是:
int num=10; int min=Math.min(num,100); System.out.println(min);如果當(dāng)前調(diào)試的是第二行,當(dāng)點(diǎn)擊step over時(shí),Math.min(num,100)方法先執(zhí)行完后跳到第三行.
Step Into
單步跳入,執(zhí)行該操作將導(dǎo)致程序向下執(zhí)行一行。如果該行有自定義的方法,則進(jìn)入該方法內(nèi)部繼續(xù)執(zhí)行,需要注意如果是類(lèi)庫(kù)中的方法,則不會(huì)進(jìn)入方法內(nèi)部。
Force Step Into
強(qiáng)制單步跳入,和step into功能類(lèi)似,主要區(qū)別在于:如果當(dāng)前行有任何方法,則不管該方法是我們自行定義還是類(lèi)庫(kù)提供的,都能跳入到方法內(nèi)部繼續(xù)執(zhí)行
Drop Frame
沒(méi)有好記的名字,大意理解為中斷執(zhí)行,并返回到方法執(zhí)行的初始點(diǎn),在這個(gè)過(guò)程中該方法對(duì)應(yīng)的棧幀會(huì)從棧中移除.換言之,如果該方法是被調(diào)用的,則返回到當(dāng)前方法被調(diào)用處,并且所有上下文變量的值也恢復(fù)到該方法未執(zhí)行時(shí)的狀態(tài)。簡(jiǎn)單的舉例來(lái)說(shuō)明:
public class DebugDemo {private String name = "default";public void alertName() {System.out.println(name);debug();}public void debug() {this.name = "debug";}public static void main(String[] args) {new DebugDemo().alertName();} }當(dāng)你在調(diào)試debug()時(shí),執(zhí)行該操作,將回調(diào)到debug()被調(diào)用的地方,也就是alertName()方法。如果此時(shí)再繼續(xù)執(zhí)行drop frame,將回調(diào)到alertName()被調(diào)用的地方,也就是main().
Force Run to Cursor
非常好用的一個(gè)功能,可以忽視已經(jīng)存在的斷點(diǎn),跳轉(zhuǎn)到光標(biāo)所在處.舉個(gè)簡(jiǎn)單例子說(shuō)明下:
比如現(xiàn)在第10行,此時(shí)我想調(diào)試18行而又不想一步一步調(diào)試,能不能一次到位呢?我們只需要將光標(biāo)定位到相應(yīng)的位置,然后執(zhí)行Force Run to Cursor即可:
Evaluate expression
點(diǎn)擊該按鈕會(huì)在當(dāng)前調(diào)試的語(yǔ)句處嵌入一個(gè)交互式解釋器,在該解釋器中,你可以執(zhí)行任何你想要執(zhí)行的表達(dá)式進(jìn)行求值操作。比如,我們?cè)谡{(diào)試時(shí)執(zhí)行到以下代碼:
此時(shí)執(zhí)行Evaluate Expression,就相當(dāng)于在調(diào)試行之前嵌入了一個(gè)交互式解釋器,那么在該解釋器中我們能做什么呢?在這里,我們可以對(duì)result進(jìn)行求值操作:對(duì)著你想要求值得位置點(diǎn)擊鼠標(biāo)右鍵,選擇evaluate Expression.此時(shí)會(huì)顯示如下:
在彈出的輸入框中輸入求值表達(dá)式,比如這里我們輸入Math.min(result,50),如下圖
點(diǎn)擊執(zhí)行,我們發(fā)現(xiàn)在Result中已經(jīng)輸出了結(jié)果,如下:
斷點(diǎn)管理區(qū)
Return
點(diǎn)擊該按鈕會(huì)停止目前的應(yīng)用,并且重新啟動(dòng).換言之,就是你想要重新調(diào)試時(shí),可以使用該操作,嗯,就是重新來(lái)過(guò)的意思.
Pause Program
點(diǎn)擊該按鈕將暫停應(yīng)用的執(zhí)行.如果想要恢復(fù)則可以使用下面提到的Resume Program.
Resume Program
該操作有恢復(fù)應(yīng)用的含義,但是卻有兩種行為:
在應(yīng)用處在暫停狀態(tài)下,點(diǎn)擊該按鈕將恢復(fù)應(yīng)用運(yùn)行.
在很多情況下,我們會(huì)設(shè)置多個(gè)斷點(diǎn)以便調(diào)試。在某些情況下,我們需要從當(dāng)前斷點(diǎn)移動(dòng)到下一個(gè)斷點(diǎn)處,兩個(gè)斷點(diǎn)之間的代碼自動(dòng)被執(zhí)行,這樣我們就不需要一步一步調(diào)試到下一個(gè)斷點(diǎn)了,省時(shí)又省力。舉例說(shuō)明:
假設(shè)我們分別在第2行和第4行添加了斷點(diǎn)。如果此時(shí)我們調(diào)試在第2行,此時(shí)點(diǎn)擊執(zhí)行該操作,當(dāng)前調(diào)試位置會(huì)自動(dòng)執(zhí)行到第4行,也就是第2到第4行之間的代碼會(huì)自動(dòng)被執(zhí)行。
Stop
點(diǎn)擊該按鈕會(huì)通過(guò)相關(guān)的關(guān)閉腳本來(lái)終止當(dāng)前進(jìn)程.換言之,對(duì)不同類(lèi)型的工程可能有不同的停止行為,比如:對(duì)普通的Java項(xiàng)目,點(diǎn)擊該按鈕意味著退出調(diào)試模式,但是應(yīng)用還會(huì)執(zhí)行完成.而在Android項(xiàng)目中,點(diǎn)擊該按鈕,則意味這app結(jié)束運(yùn)行.
這里我們以一個(gè)普通的JAVA工程為例:
此時(shí)如果我們執(zhí)行停止操作,發(fā)現(xiàn)程序退出調(diào)試模式,并正常執(zhí)行完畢,Console中結(jié)果如下:
View Breakpoints
點(diǎn)擊該按鈕會(huì)進(jìn)入斷點(diǎn)管理界面,在這里你可以查看所有斷點(diǎn),管理或者配置斷點(diǎn)的行為,如:刪除,修改屬性信息等:
Mute Breakpoints
使用該按鈕來(lái)切換斷點(diǎn)的狀態(tài):啟動(dòng)或者禁用.在調(diào)試過(guò)程中,你可以禁用暫時(shí)禁用所有的斷點(diǎn),已實(shí)現(xiàn)應(yīng)用正常的運(yùn)行.該功能非常有用,比如當(dāng)你在調(diào)試過(guò)程中,突然不想讓斷點(diǎn)干擾你所關(guān)心的流程時(shí),可以臨時(shí)禁用斷點(diǎn).
Get thread dump
獲取線(xiàn)程Dump,點(diǎn)擊該按鈕將進(jìn)入線(xiàn)程Dump界面:
借此我們順便介紹一下dump界面,線(xiàn)程工具區(qū)中最常用的是
,可以用來(lái)過(guò)濾線(xiàn)程,其他的不做解釋了
解析來(lái)我們來(lái)認(rèn)識(shí)一下線(xiàn)程的類(lèi)型,表示為不同的圖標(biāo):
| Thread is suspended | |
| Thread is waiting on a monitor lock | |
| Thread is running | |
| Thread is executing network operation, and is waiting for data to be passed | |
| Thread is idle | |
| Event Dispatch Thread that is busy | |
| Thread is executing disk operation |
Settings
點(diǎn)擊該按鈕將打開(kāi)有關(guān)設(shè)置的列表:
我們對(duì)其中的幾個(gè)進(jìn)行說(shuō)明:
Show Values Inline
調(diào)試過(guò)程中開(kāi)啟該功能,將會(huì)代碼右邊顯示變量值,即下圖中紅框所示部分:
Show Method Return Values
調(diào)試過(guò)程中啟用該功能,將在變量區(qū)顯示最后執(zhí)行方法的返回值.舉個(gè)例子來(lái)說(shuō),首先,關(guān)閉該功能,我們調(diào)試這段代碼并觀察其變量區(qū):
開(kāi)啟該功能之后,再來(lái)觀察變量區(qū)的變化:
繼續(xù)往下調(diào)試:
繼續(xù)往下調(diào)試:
這個(gè)功能簡(jiǎn)直是棒極了,在調(diào)試一段代碼,并想看該代碼中最后調(diào)用方法的最終結(jié)果時(shí)就非常有用了.
Auto-Variables Mode
開(kāi)啟這個(gè)功能后,idea的Debugger會(huì)自動(dòng)評(píng)估某些變量,大概就是當(dāng)你執(zhí)行在某個(gè)斷點(diǎn)時(shí),Debugger會(huì)檢測(cè)當(dāng)前調(diào)試點(diǎn)之前或者之后的變量的狀態(tài),然后在變量區(qū)選擇性輸出.舉個(gè)例子來(lái)說(shuō)明,未開(kāi)啟該功能之前,變量區(qū)輸出所有的變量信息:
開(kāi)啟之后,當(dāng)你調(diào)試到第13行時(shí),Debugger檢測(cè)到num變量在之后沒(méi)有被使用,那么在變量區(qū)就不會(huì)輸出該變量的信息.
Sort values alphabetically
開(kāi)啟這個(gè)功能的化,變量區(qū)中的輸出內(nèi)容會(huì)按照按字母順序進(jìn)行排序,很簡(jiǎn)單,不常用,還是按照默認(rèn)的順序好.
Help
這個(gè)不用說(shuō)了,有任何不明白的都可以查看官方幫助文檔,這是我見(jiàn)到最好的文檔之一.
其他幾個(gè)操作:Settings,Pin,Close留給各位自己去使用.
修改變量值
在調(diào)試過(guò)程中,我們可以方便的修改某個(gè)變量的值,如下:
在上圖中,當(dāng)前result的值經(jīng)過(guò)計(jì)算為10,這里我們通過(guò)Set Value將其計(jì)算結(jié)果修改為100.
變量觀察區(qū)
該區(qū)域?qū)@示你所感興趣的變量的值。在調(diào)試模式下,你可以通過(guò)Add to Watches將某個(gè)變量添加到觀察區(qū),該值的變化將會(huì)在變量觀察區(qū)顯示。操作如下:
這里我們對(duì)name比較感興趣,希望看到它的值的變化情況,因此我們將其“特殊關(guān)照”。需要注意,此時(shí)因?yàn)閚ame是成員變量,因此在對(duì)象觀察區(qū)也可看到該值。如果是局部變量,無(wú)疑只能用這種方式了。
斷點(diǎn)的分類(lèi)
到目前為止,我們已經(jīng)簡(jiǎn)單的介紹了調(diào)試功能區(qū),斷點(diǎn)管理區(qū),求值表達(dá)式,這三個(gè)區(qū)域的功能。在上面,我們不斷的提到了斷點(diǎn)一次,但是斷點(diǎn)是什么呢?想必大部分人已經(jīng)知道了,我們這里在簡(jiǎn)單的說(shuō)明下:
斷點(diǎn)是調(diào)試器的功能之一,可以讓程序暫停在需要的地方,幫助我們進(jìn)行分析程序的運(yùn)行過(guò)程。
在Android Studio中,斷點(diǎn)又被以下五類(lèi):
- 條件斷點(diǎn)
- 日志斷點(diǎn)
- 異常斷點(diǎn)
- 方法斷點(diǎn)
- 屬性斷點(diǎn)
其中方法斷點(diǎn)是我們最熟悉的斷點(diǎn)類(lèi)型,相信沒(méi)有人不會(huì)。下面我們著重介紹其他四種類(lèi)型的斷點(diǎn)。
條件斷點(diǎn)
所謂的條件斷點(diǎn)就是在特定條件發(fā)生的斷點(diǎn),也就是,我們可將某個(gè)斷點(diǎn)設(shè)置為只對(duì)某種事件感興趣,最典型的應(yīng)用就是在列表循環(huán)中,我們希望在某特定的元素出現(xiàn)時(shí)暫停程序運(yùn)行。比如,現(xiàn)在我們有個(gè)list中,其中包含了q,1q,2q,3q四個(gè)元素,我們希望在遍歷到2q時(shí)暫停程序運(yùn)行,那么需要進(jìn)行如下操作,在需要的地方添加斷點(diǎn),如下:
斷點(diǎn)處左鍵單擊,在Condition處填寫(xiě)過(guò)濾條件.此處我們只關(guān)心2q,因此填寫(xiě)s.equals(“2q”)
日志斷點(diǎn)
該類(lèi)型的斷點(diǎn)不會(huì)使程序停下來(lái),而是在輸出我們要它輸出的日志信息,然后繼續(xù)執(zhí)行。具體操作如下:同樣在斷點(diǎn)處左鍵單擊,在彈出的對(duì)話(huà)框中取消選中Suspend。
在彈出的控制面板中,選中Log evaluated expression,然后再填寫(xiě)想要輸出的日志信息,如下:
當(dāng)調(diào)試過(guò)程遇到該斷點(diǎn)將會(huì)輸出結(jié)果,如下:
異常斷點(diǎn)
所謂的異常斷點(diǎn)就是在調(diào)試過(guò)程中,一旦發(fā)生異常(可以指定某類(lèi)異常),則會(huì)立刻定位到異常拋出的地方。比如在調(diào)試異常中,我們非常關(guān)注運(yùn)行時(shí)異常,希望在產(chǎn)生任何運(yùn)行異常時(shí)及時(shí)定位,那么此時(shí)就可以利用該類(lèi)型異常,在上線(xiàn)之前,進(jìn)行異常斷點(diǎn)調(diào)試非常有利于減少正式環(huán)境中發(fā)生crash的幾率。
具體操作如下:在Run菜單項(xiàng)中,選擇View Breakpoints(也可以在斷點(diǎn)管理面板中點(diǎn)擊 ),如下:
在管理斷點(diǎn)面板中,點(diǎn)擊+
在彈出的下拉選擇列表中,我們選擇Java Exception Breakpoints
這里我們選中Search By Name,在下面的輸入框中輸入我們所關(guān)心的異常類(lèi)型。此處我們關(guān)心NullPointerException,在調(diào)試過(guò)程一旦發(fā)生NullPointerException,調(diào)試器就會(huì)定位到異常發(fā)生處。
方法斷點(diǎn)
(略過(guò)吧,應(yīng)該沒(méi)人不知道了)
Field WatchPoint
Filed WatchPoint是本質(zhì)上是一種特殊的斷點(diǎn),也稱(chēng)為屬性斷點(diǎn):當(dāng)我們某個(gè)字段值被修改的時(shí)候,程序暫停在修改處。通常在調(diào)試多線(xiàn)程時(shí)尤為可用,能幫我們及時(shí)的定位并發(fā)錯(cuò)誤的問(wèn)題。其使用和添加普通的斷點(diǎn)并無(wú)不同,斷點(diǎn)圖標(biāo)稍有不同
調(diào)試的兩種方式
到目前,調(diào)試的相關(guān)基礎(chǔ)我們已經(jīng)介紹完了,但是不少童鞋對(duì)Android Studio中
這兩個(gè)按鈕感到困惑:Debug和Attach process。
這里我們就簡(jiǎn)單介紹一下這兩者的區(qū)別:
Debug
以調(diào)試模式安裝運(yùn)行,斷點(diǎn)可以在運(yùn)行之前設(shè)置,也可在運(yùn)行后設(shè)置,是多數(shù)人最常用的調(diào)式方式
Attach process
和Debug方式相比,能夠?qū)⒄{(diào)試器attach到任何正在運(yùn)行的進(jìn)程。比如,我們可以通過(guò)attach process到想要調(diào)試的進(jìn)程。然后,在需要的地方設(shè)置相關(guān)斷點(diǎn)即可。
在具體調(diào)試過(guò)程,自行酌情選擇即可。后面,我會(huì)帶大家一步一步調(diào)試Android的Framework相關(guān)的源碼,參見(jiàn):自己動(dòng)手編譯最新Android源碼及SDK及自己動(dòng)手調(diào)試Android源碼
總結(jié)
以上是生活随笔為你收集整理的你所不知道的Android Studio调试技巧的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Android开发常用开源框架:图片处理
- 下一篇: Android应用坐标系统全面详解