你所不知道的Android Studio調(diào)試技巧

Android Studio目前已經(jīng)成為開發(fā)Android的主要工具,用熟了可謂相當順手。作為開發(fā)者,調(diào)試并發(fā)現(xiàn)bug,進而解決,可是我們的看家本領(lǐng)。正所謂,工欲善其事必先利其器,和其他開發(fā)工具一樣,如Eclipse、Idea,Android Studio也為我們提供了強大的調(diào)試技巧,今天我們就來看看Android Studio中有關(guān)調(diào)試的技巧。

首先,來看看Android studio中為我們提供的調(diào)試面板(標準情況下):


這里寫圖片描述

點擊右上角Restore ‘Threads’View可先展示目前相關(guān)的線程信息:


這里寫圖片描述

android studio大體為我們提供了7個功能區(qū):

  1. 單步調(diào)試區(qū)
  2. 斷點管理區(qū)
  3. 求值表達式
  4. 線程幀棧區(qū)
  5. 對象變量區(qū)
  6. 變量觀察區(qū)

下面我們分別對這七個區(qū)域進行介紹。


單步調(diào)試區(qū)

該區(qū)提供了調(diào)試的主要操作,和你所熟知的一樣的,主要有:Step over、step into、force step into、step out、drop frame。

Show Execution Point
這里寫圖片描述

點擊該按鈕,光標將定位到當前正在調(diào)試的位置.

Step Over
這里寫圖片描述

單步跳過,點擊該按鈕將導致程序向下執(zhí)行一行。如果當前行是一個方法調(diào)用,此行調(diào)用的方法被執(zhí)行完畢后再到下一行。比如當前代碼是:

int num=10;
int min=Math.min(num,100);
System.out.println(min);

如果當前調(diào)試的是第二行,當點擊step over時,Math.min(num,100)方法先執(zhí)行完后跳到第三行.

Step Into
這里寫圖片描述

單步跳入,執(zhí)行該操作將導致程序向下執(zhí)行一行。如果該行有自定義的方法,則進入該方法內(nèi)部繼續(xù)執(zhí)行,需要注意如果是類庫中的方法,則不會進入方法內(nèi)部。

Force Step Into
這里寫圖片描述

強制單步跳入,和step into功能類似,主要區(qū)別在于:如果當前行有任何方法,則不管該方法是我們自行定義還是類庫提供的,都能跳入到方法內(nèi)部繼續(xù)執(zhí)行

Drop Frame
這里寫圖片描述

沒有好記的名字,大意理解為中斷執(zhí)行,并返回到方法執(zhí)行的初始點,在這個過程中該方法對應的棧幀會從棧中移除.換言之,如果該方法是被調(diào)用的,則返回到當前方法被調(diào)用處,并且所有上下文變量的值也恢復到該方法未執(zhí)行時的狀態(tài)。簡單的舉例來說明:

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();
    }
}

當你在調(diào)試debug()時,執(zhí)行該操作,將回調(diào)到debug()被調(diào)用的地方,也就是alertName()方法。如果此時再繼續(xù)執(zhí)行drop frame,將回調(diào)到alertName()被調(diào)用的地方,也就是main().

Force Run to Cursor
這里寫圖片描述

非常好用的一個功能,可以忽視已經(jīng)存在的斷點,跳轉(zhuǎn)到光標所在處.舉個簡單例子說明下:


這里寫圖片描述

比如現(xiàn)在第10行,此時我想調(diào)試18行而又不想一步一步調(diào)試,能不能一次到位呢?我們只需要將光標定位到相應的位置,然后執(zhí)行Force Run to Cursor即可:


這里寫圖片描述

Evaluate expression
這里寫圖片描述

點擊該按鈕會在當前調(diào)試的語句處嵌入一個交互式解釋器,在該解釋器中,你可以執(zhí)行任何你想要執(zhí)行的表達式進行求值操作。比如,我們在調(diào)試時執(zhí)行到以下代碼:


這里寫圖片描述

此時執(zhí)行Evaluate Expression,就相當于在調(diào)試行之前嵌入了一個交互式解釋器,那么在該解釋器中我們能做什么呢?在這里,我們可以對result進行求值操作:對著你想要求值得位置點擊鼠標右鍵,選擇evaluate Expression.此時會顯示如下:


這里寫圖片描述

在彈出的輸入框中輸入求值表達式,比如這里我們輸入Math.min(result,50),如下圖

這里寫圖片描述

點擊執(zhí)行,我們發(fā)現(xiàn)在Result中已經(jīng)輸出了結(jié)果,如下:


這里寫圖片描述

斷點管理區(qū)

Return
這里寫圖片描述

點擊該按鈕會停止目前的應用,并且重新啟動.換言之,就是你想要重新調(diào)試時,可以使用該操作,嗯,就是重新來過的意思.

Pause Program
這里寫圖片描述

點擊該按鈕將暫停應用的執(zhí)行.如果想要恢復則可以使用下面提到的Resume Program.

Resume Program
這里寫圖片描述

該操作有恢復應用的含義,但是卻有兩種行為:

  1. 在應用處在暫停狀態(tài)下,點擊該按鈕將恢復應用運行.
  2. 在很多情況下,我們會設(shè)置多個斷點以便調(diào)試。在某些情況下,我們需要從當前斷點移動到下一個斷點處,兩個斷點之間的代碼自動被執(zhí)行,這樣我們就不需要一步一步調(diào)試到下一個斷點了,省時又省力。舉例說明:
public void test(){
    test1();
    ...
    test2();

}

假設(shè)我們分別在第2行和第4行添加了斷點。如果此時我們調(diào)試在第2行,此時點擊執(zhí)行該操作,當前調(diào)試位置會自動執(zhí)行到第4行,也就是第2到第4行之間的代碼會自動被執(zhí)行。

Stop
這里寫圖片描述

點擊該按鈕會通過相關(guān)的關(guān)閉腳本來終止當前進程.換言之,對不同類型的工程可能有不同的停止行為,比如:對普通的Java項目,點擊該按鈕意味著退出調(diào)試模式,但是應用還會執(zhí)行完成.而在Android項目中,點擊該按鈕,則意味這app結(jié)束運行.

這里我們以一個普通的JAVA工程為例:


這里寫圖片描述

此時如果我們執(zhí)行停止操作,發(fā)現(xiàn)程序退出調(diào)試模式,并正常執(zhí)行完畢,Console中結(jié)果如下:


這里寫圖片描述

View Breakpoints
這里寫圖片描述

點擊該按鈕會進入斷點管理界面,在這里你可以查看所有斷點,管理或者配置斷點的行為,如:刪除,修改屬性信息等:


這里寫圖片描述

Mute Breakpoints
這里寫圖片描述

使用該按鈕來切換斷點的狀態(tài):啟動或者禁用.在調(diào)試過程中,你可以禁用暫時禁用所有的斷點,已實現(xiàn)應用正常的運行.該功能非常有用,比如當你在調(diào)試過程中,突然不想讓斷點干擾你所關(guān)心的流程時,可以臨時禁用斷點.

Get thread dump
這里寫圖片描述

獲取線程Dump,點擊該按鈕將進入線程Dump界面:


這里寫圖片描述

借此我們順便介紹一下dump界面:

線程工具區(qū)中最常用的是
這里寫圖片描述
,可以用來過濾線程,其他的不做解釋了

解析來我們來認識一下線程的類型,表示為不同的圖標:

線程狀態(tài)描述 圖標
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
這里寫圖片描述

點擊該按鈕將打開有關(guān)設(shè)置的列表:


這里寫圖片描述

我們對其中的幾個進行說明:

Show Values Inline

調(diào)試過程中開啟該功能,將會代碼右邊顯示變量值,即下圖中紅框所示部分:


這里寫圖片描述

Show Method Return Values

調(diào)試過程中啟用該功能,將在變量區(qū)顯示最后執(zhí)行方法的返回值.舉個例子來說,首先,關(guān)閉該功能,我們調(diào)試這段代碼并觀察其變量區(qū):


這里寫圖片描述

開啟該功能之后,再來觀察變量區(qū)的變化:


這里寫圖片描述

繼續(xù)往下調(diào)試:


這里寫圖片描述

繼續(xù)往下調(diào)試:


這里寫圖片描述

這個功能簡直是棒極了,在調(diào)試一段代碼,并想看該代碼中最后調(diào)用方法的最終結(jié)果時就非常有用了.

Auto-Variables Mode

開啟這個功能后,idea的Debugger會自動評估某些變量,大概就是當你執(zhí)行在某個斷點時,Debugger會檢測當前調(diào)試點之前或者之后的變量的狀態(tài),然后在變量區(qū)選擇性輸出.舉個例子來說明,未開啟該功能之前,變量區(qū)輸出所有的變量信息:


這里寫圖片描述

開啟之后,當你調(diào)試到第13行時,Debugger檢測到num變量在之后沒有被使用,那么在變量區(qū)就不會輸出該變量的信息.


這里寫圖片描述

Sort values alphabetically

開啟這個功能的化,變量區(qū)中的輸出內(nèi)容會按照按字母順序進行排序,很簡單,不常用,還是按照默認的順序好.

Help
這里寫圖片描述

這個不用說了,有任何不明白的都可以查看官方幫助文檔,這是我見到最好的文檔之一.
其他幾個操作:Settings,Pin,Close留給各位自己去使用.


修改變量值

在調(diào)試過程中,我們可以方便的修改某個變量的值,如下:


這里寫圖片描述

在上圖中,當前result的值經(jīng)過計算為10,這里我們通過Set Value將其計算結(jié)果修改為100.


變量觀察區(qū)

該區(qū)域?qū)@示你所感興趣的變量的值。在調(diào)試模式下,你可以通過Add to Watches將某個變量添加到觀察區(qū),該值的變化將會在變量觀察區(qū)顯示。操作如下:


這里寫圖片描述

這里我們對name比較感興趣,希望看到它的值的變化情況,因此我們將其“特殊關(guān)照”。需要注意,此時因為name是成員變量,因此在對象觀察區(qū)也可看到該值。如果是局部變量,無疑只能用這種方式了。


斷點的分類

到目前為止,我們已經(jīng)簡單的介紹了調(diào)試功能區(qū),斷點管理區(qū),求值表達式,這三個區(qū)域的功能。在上面,我們不斷的提到了斷點一次,但是斷點是什么呢?想必大部分人已經(jīng)知道了,我們這里在簡單的說明下:

斷點是調(diào)試器的功能之一,可以讓程序暫停在需要的地方,幫助我們進行分析程序的運行過程。

在Android Studio中,斷點又被以下五類:

  1. 條件斷點
  2. 日志斷點
  3. 異常斷點
  4. 方法斷點
  5. 屬性斷點

其中方法斷點是我們最熟悉的斷點類型,相信沒有人不會。下面我們著重介紹其他四種類型的斷點。

條件斷點

所謂的條件斷點就是在特定條件發(fā)生的斷點,也就是,我們可將某個斷點設(shè)置為只對某種事件感興趣,最典型的應用就是在列表循環(huán)中,我們希望在某特定的元素出現(xiàn)時暫停程序運行。比如,現(xiàn)在我們有個list中,其中包含了q,1q,2q,3q四個元素,我們希望在遍歷到2q時暫停程序運行,那么需要進行如下操作:
在需要的地方添加斷點,如下:


這里寫圖片描述

斷點處左鍵單擊,在Condition處填寫過濾條件.此處我們只關(guān)心2q,因此填寫s.equals("2q")

這里寫圖片描述

日志斷點

該類型的斷點不會使程序停下來,而是在輸出我們要它輸出的日志信息,然后繼續(xù)執(zhí)行。具體操作如下:
同樣在斷點處左鍵單擊,在彈出的對話框中取消選中Suspend。


這里寫圖片描述

在彈出的控制面板中,選中Log evaluated expression,然后再填寫想要輸出的日志信息,如下:


這里寫圖片描述

當調(diào)試過程遇到該斷點將會輸出結(jié)果,如下:


這里寫圖片描述

異常斷點

所謂的異常斷點就是在調(diào)試過程中,一旦發(fā)生異常(可以指定某類異常),則會立刻定位到異常拋出的地方。比如在調(diào)試異常中,我們非常關(guān)注運行時異常,希望在產(chǎn)生任何運行異常時及時定位,那么此時就可以利用該類型異常,在上線之前,進行異常斷點調(diào)試非常有利于減少正式環(huán)境中發(fā)生crash的幾率。

具體操作如下:在Run菜單項中,選擇View Breakpoints(也可以在斷點管理面板中點擊
這里寫圖片描述
),如下:
這里寫圖片描述

在管理斷點面板中,點擊+

這里寫圖片描述

在彈出的下拉選擇列表中,我們選擇Java Exception Breakpoints


這里寫圖片描述

這里我們選中Search By Name,在下面的輸入框中輸入我們所關(guān)心的異常類型。此處我們關(guān)心NullPointerException,在調(diào)試過程一旦發(fā)生NullPointerException,調(diào)試器就會定位到異常發(fā)生處。


這里寫圖片描述

方法斷點
這里寫圖片描述

(略過吧,應該沒人不知道了)

Filed WatchPoint
這里寫圖片描述

Filed WatchPoint是本質(zhì)上是一種特殊的斷點,也稱為屬性斷點:當我們某個字段值被修改的時候,程序暫停在修改處。通常在調(diào)試多線程時尤為可用,能幫我們及時的定位并發(fā)錯誤的問題。其使用和添加普通的斷點并無不同,斷點圖標稍有不同


調(diào)試的兩種方式

到目前,調(diào)試的相關(guān)基礎(chǔ)我們已經(jīng)介紹完了,但是不少童鞋對Android Studio中
這里寫圖片描述

這兩個按鈕感到困惑:Debug和Attach process。
這里我們就簡單介紹一下這兩者的區(qū)別:

  • Debug:以調(diào)試模式安裝運行,斷點可以在運行之前設(shè)置,也可在運行后設(shè)置,是多數(shù)人最常用的調(diào)式方式
  • Attach process:和Debug方式相比,能夠?qū)⒄{(diào)試器attach到任何正在運行的進程。比如,我們可以通過attach process到想要調(diào)試的進程。然后,在需要的地方設(shè)置相關(guān)斷點即可。

在具體調(diào)試過程,自行酌情選擇即可。后面,我會帶大家一步一步調(diào)試Android的Framework相關(guān)的源碼,參見:
自己動手編譯最新Android源碼及SDK自己動手調(diào)試Android源碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • Android Studio目前已經(jīng)成為開發(fā)Android的主要工具,用熟了可謂相當順手。作為開發(fā)者,調(diào)試并發(fā)現(xiàn)b...
    7d3fadbb4407閱讀 626評論 0 3
  • Android Studio目前已經(jīng)成為開發(fā)Android的主要工具,用熟了可謂相當順手。作為開發(fā)者,調(diào)試并發(fā)現(xiàn)b...
    StChris閱讀 1,855評論 0 16
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,347評論 25 708
  • 我和一個女生認識了好久,每天也聊的都挺好,我覺得和她聊天很開心,直到前段時間,她突然跟我表白了,讓我做她男朋友...
    做我懷里的懶貓閱讀 1,059評論 0 0
  • 你的青春記憶里有沒有一個叫周杰倫的人,當我們告別學生時代,告別青春,時間也僅僅是讓他上揚了嘴角。謝謝,陪伴了我們整...
    吾愛家閱讀 2,874評論 0 1

友情鏈接更多精彩內(nèi)容