標籤:
Android Studio目前已經成為開發Android的主要工具,用熟了可謂相當順手。作為開發人員,調試並發現bug,進而解決,可是我們的看家本領。正所謂,工欲善其事必先利其器,和其他開發工具一樣,如Eclipse、Idea,Android Studio也為我們提供了強大的調試技巧,今天我們就來看看Android Studio中有關調試的技巧。
首先,來看看Android studio中為我們提供的調試面板(標準情況下):
這裡寫圖片描述
點擊右上方Restore ‘Threads’View可先展示目前相關的線程資訊:
這裡寫圖片描述
android studio大體為我們提供了7個功能區:
- 單步調試區
- 斷點管理區
- 求值運算式
- 線程幀棧區
- 物件變數區
- 變數觀察區
下面我們分別對這七個地區進行介紹。
單步調試區
該區提供了調試的主要操作,和你所熟知的一樣的,主要有:Step over、step into、force step into、step out、drop frame。
Show Execution Point
這裡寫圖片描述
點擊該按鈕,游標將定位到當前正在調試的位置.
Step Over
這裡寫圖片描述
單步跳過,點擊該按鈕將導致程式向下執行一行。如果當前行是一個方法調用,此行調用的方法被執行完畢後再到下一行。比如當前代碼是:
int num=10;int min=Math.min(num,100);System.out.println(min);
如果當前調試的是第二行,當點擊step over時,Math.min(num,100)方法先執行完後跳到第三行.
Step Into
這裡寫圖片描述
單步跳入,執行該操作將導致程式向下執行一行。如果該行有自訂的方法,則進入該方法內部繼續執行,需要注意如果是類庫中的方法,則不會進入方法內部。
Force Step Into
這裡寫圖片描述
強制單步跳入,和step into功能類似,主要區別在於:如果當前行有任何方法,則不管該方法是我們自行定義還是類庫提供的,都能跳入到方法內部繼續執行
Drop Frame
這裡寫圖片描述
沒有好記的名字,大意理解為中斷執行,並返回到方法執行的初始點,在這個過程中該方法對應的棧幀會從棧中移除.換言之,如果該方法是被調用的,則返回到當前方法被調用處,並且所有上下文變數的值也恢複到該方法未執行時的狀態。簡單的舉例來說明:
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(); }}
當你在調試debug()時,執行該操作,將回調到debug()被調用的地方,也就是alertName()方法。如果此時再繼續執行drop frame,將回調到alertName()被調用的地方,也就是main().
Force Run to Cursor
這裡寫圖片描述
非常好用的一個功能,可以忽視已經存在的斷點,跳轉到游標所在處.舉個簡單例子說明下:
這裡寫圖片描述
比如現在第10行,此時我想調試18行而又不想一步一步調試,能不能一次到位呢?我們只需要將游標定位到相應的位置,然後執行Force Run to Cursor即可:
這裡寫圖片描述Evaluate expression
這裡寫圖片描述
點擊該按鈕會在當前調試的語句處嵌入一個互動式解譯器,在該解譯器中,你可以執行任何你想要執行的運算式進行求值操作。比如,我們在調試時執行到以下代碼:
這裡寫圖片描述
此時執行Evaluate Expression,就相當於在調試行之前嵌入了一個互動式解譯器,那麼在該解譯器中我們能做什麼呢?在這裡,我們可以對result進行求值操作:對著你想要求值得位置點擊滑鼠右鍵,選擇evaluate Expression.此時會顯示如下:
這裡寫圖片描述
在彈出的輸入框中輸入求值運算式,比如這裡我們輸入Math.min(result,50),如
這裡寫圖片描述
點擊執行,我們發現在Result中已經輸出了結果,如下:
這裡寫圖片描述斷點管理區Return
這裡寫圖片描述
點擊該按鈕會停止目前的應用,並且重新啟動.換言之,就是你想要重新調試時,可以使用該操作,嗯,就是重新來過的意思.
Pause Program
這裡寫圖片描述
點擊該按鈕將暫停應用的執行.如果想要恢複則可以使用下面提到的Resume Program.
Resume Program
這裡寫圖片描述
該操作有恢複應用的含義,但是卻有兩種行為:
- 在應用處在暫停狀態下,點擊該按鈕將恢複應用運行.
- 在很多情況下,我們會設定多個斷點以便調試。在某些情況下,我們需要從當前斷點移動到下一個斷點處,兩個斷點之間的代碼自動被執行,這樣我們就不需要一步一步調試到下一個斷點了,省時又省力。舉例說明:
public void test(){ test1(); ... test2();}
假設我們分別在第2行和第4行添加了斷點。如果此時我們調試在第2行,此時點擊執行該操作,當前調試位置會自動執行到第4行,也就是第2到第4行之間的代碼會自動被執行。
Stop
這裡寫圖片描述
點擊該按鈕會通過相關的關閉指令碼來終止當前進程.換言之,對不同類型的工程可能有不同的停止行為,比如:對普通的Java項目,點擊該按鈕意味著退出偵錯模式,但是應用還會執行完成.而在Android項目中,點擊該按鈕,則意味這app結束運行.
這裡我們以一個普通的JAVA工程為例:
這裡寫圖片描述
此時如果我們執行停止操作,發現程式退出偵錯模式,並正常執行完畢,Console中結果如下:
這裡寫圖片描述View Breakpoints
這裡寫圖片描述
點擊該按鈕會進入斷點管理介面,在這裡你可以查看所有斷點,管理或者配置斷點的行為,如:刪除,修改屬性資訊等:
這裡寫圖片描述Mute Breakpoints
這裡寫圖片描述
使用該按鈕來切換斷點的狀態:啟動或者禁用.在調試過程中,你可以禁用暫時禁用所有的斷點,已實現應用正常的運行.該功能非常有用,比如當你在調試過程中,突然不想讓斷點幹擾你所關心的流程時,可以臨時禁用斷點.
Get thread dump
這裡寫圖片描述
擷取線程Dump,點擊該按鈕將進入線程Dump介面:
這裡寫圖片描述
藉此我們順便介紹一下dump介面:
線程工具區中最常用的是
這裡寫圖片描述
,可以用來過濾線程,其他的不做解釋了
解析來我們來認識一下線程的類型,表示為不同的表徵圖:
| 線程狀態原因 |
表徵圖 |
| 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
這裡寫圖片描述
點擊該按鈕將開啟有關設定的列表:
這裡寫圖片描述
我們對其中的幾個進行說明:
Show Values Inline
調試過程中開啟該功能,將會代碼右邊顯示變數值,即中紅框所示部分:
這裡寫圖片描述Show Method Return Values
調試過程中啟用該功能,將在變數區顯示最後執行方法的返回值.舉個例子來說,首先,關閉該功能,我們調試這段代碼並觀察其變數區:
這裡寫圖片描述
開啟該功能之後,再來觀察變數區的變化:
這裡寫圖片描述
繼續往下調試:
這裡寫圖片描述
繼續往下調試:
這裡寫圖片描述
這個功能簡直是棒極了,在調試一段代碼,並想看該代碼中最後調用方法的最終結果時就非常有用了.
Auto-Variables Mode
開啟這個功能後,idea的Debugger會自動評估某些變數,大概就是當你執行在某個斷點時,Debugger會檢測當前調試驗之前或者之後的變數的狀態,然後在變數區選擇性輸出.舉個例子來說明,未開啟該功能之前,變數區輸出所有的變數資訊:
這裡寫圖片描述
開啟之後,當你調試到第13行時,Debugger檢測到num變數在之後沒有被使用,那麼在變數區就不會輸出該變數的資訊.
這裡寫圖片描述Sort values alphabetically
開啟這個功能的化,變數區中的輸出內容會按照按字母順序進行排序,很簡單,不常用,還是按照預設的順序好.
Help
這裡寫圖片描述
這個不用說了,有任何不明白的都可以查看官方協助文檔,這是我見到最好的文檔之一.
其他幾個操作:Settings,Pin,Close留給各位自己去使用.
修改變數值
在調試過程中,我們可以方便的修改某個變數的值,如下:
這裡寫圖片描述
在中,當前result的值經過計算為10,這裡我們通過Set Value將其計算結果修改為100.
變數觀察區
該地區將顯示你所感興趣的變數的值。在偵錯模式下,你可以通過Add to Watches將某個變數添加到觀察區,該值的變化將會在變數觀察區顯示。操作如下:
這裡寫圖片描述
這裡我們對name比較感興趣,希望看到它的值的變化情況,因此我們將其“特殊關照”。需要注意,此時因為name是成員變數,因此在對象觀察區也可看到該值。如果是局部變數,無疑只能用這種方式了。
斷點的分類
到目前為止,我們已經簡單的介紹了調試功能區,斷點管理區,求值運算式,這三個地區的功能。在上面,我們不斷的提到了斷點一次,但是斷點是什麼呢?想必大部分人已經知道了,我們這裡在簡單的說明下:
斷點是調試器的功能之一,可以讓程式暫停在需要的地方,協助我們進行剖析器的運行過程。
在Android Studio中,斷點又被以下五類:
- 條件斷點
- 日誌斷點
- 異常斷點
- 方法斷點
- 屬性斷點
其中方法斷點是我們最熟悉的斷點類型,相信沒有人不會。下面我們著重介紹其他四種類型的斷點。
條件斷點
所謂的條件斷點就是在特定條件發生的斷點,也就是,我們可將某個斷點設定為只對某種事件感興趣,最典型的應用就是在列表迴圈中,我們希望在某特定的元素出現時暫停程式運行。比如,現在我們有個list中,其中包含了q,1q,2q,3q四個元素,我們希望在遍曆到2q時暫停程式運行,那麼需要進行如下操作:
在需要的地方添加斷點,如下:
這裡寫圖片描述
斷點處左鍵單擊,在Condition處填寫過濾條件.此處我們只關心2q,因此填寫s.equals("2q")
這裡寫圖片描述日誌斷點
該類型的斷點不會使程式停下來,而是在輸出我們要它輸出的日誌資訊,然後繼續執行。具體操作如下:
同樣在斷點處左鍵單擊,在彈出的對話方塊中取消選中Suspend。
這裡寫圖片描述
在彈出的控制台中,選中Log evaluated expression,然後再填寫想要輸出的日誌資訊,如下:
這裡寫圖片描述
當調試過程遇到該斷點將會輸出結果,如下:
這裡寫圖片描述異常斷點
所謂的異常斷點就是在調試過程中,一旦發生異常(可以指定某類異常),則會立刻定位到異常拋出的地方。比如在調試異常中,我們非常關注運行時異常,希望在產生任何運行異常時及時定位,那麼此時就可以利用該類型異常,在上線之前,進行異常斷點調試非常有利於減少正式環境中發生crash的幾率。
具體操作如下:在Run功能表項目中,選擇View Breakpoints(也可以在斷點管理面板中點擊
這裡寫圖片描述
),如下:
這裡寫圖片描述
在管理斷點面板中,點擊+
這裡寫圖片描述
在彈出的下拉挑選清單中,我們選擇Java Exception Breakpoints
這裡寫圖片描述
這裡我們選中Search By Name,在下面的輸入框中輸入我們所關心的異常類型。此處我們關心NullPointerException,在調試過程一旦發生NullPointerException,調試器就會定位到異常發生處。
這裡寫圖片描述方法斷點
這裡寫圖片描述
(略過吧,應該沒人不知道了)
Filed WatchPoint
這裡寫圖片描述
Filed WatchPoint是本質上是一種特殊的斷點,也稱為屬性斷點:當我們某個欄位值被修改的時候,程式暫停在修改處。通常在調試多線程時尤為可用,能幫我們及時的定位並發錯誤的問題。其使用和添加普通的斷點並無不同,斷點表徵圖稍有不同
調試的兩種方式
到目前,調試的相關基礎我們已經介紹完了,但是不少童鞋對Android Studio中
這裡寫圖片描述
這兩個按鈕感到困惑:Debug和Attach process。
這裡我們就簡單介紹一下這兩者的區別:
- Debug:以偵錯模式安裝運行,斷點可以在運行之前設定,也可在運行後設定,是多數人最常用的調式方式
- Attach process:和Debug方式相比,能夠將調試器attach到任何正在啟動並執行進程。比如,我們可以通過attach process到想要調試的進程。然後,在需要的地方設定相關斷點即可。
在具體調試過程,自行酌情選擇即可。後面,我會帶大家一步一步調試Android的Framework相關的源碼,參見:
自己動手編譯最新Android源碼及SDK及自己動手調試Android源碼
你所不知道的Android Studio調試技巧