一、起因
高級IDE的Debug功能幾乎是必備的,我用的第一個Debug的IDE是Visual Studio(簡稱VS),那時還是大學。工作之后其實大多數時間開發的是業務為導向的app,調試的幾乎也就是看看某些執行流程對不對,或者某些變量的動態值,這些app大多面向網絡的,大多數是調試網絡接口,用Charles抓包然后加打印Log的方式就可以了。但最近研究AndroidFramework層的功能,簡單的調試已經不能滿足了,舉個簡單的例子,Android源碼調試,總不能每次加一行Log然后編譯一次系統吧=_=
二、從何說起
1. 如何打斷點
好像所有的IDE,打斷點的方式沒什么區別吧,就是行號旁邊點擊一下,看下圖:
上圖中的斷點有三個,分別是Java Field Watchpoints
Java Line Breakpoints
Java Method Breakpoints
,還有幾種斷點,沒法在界面中顯示出來。要想看項目中的所有的代碼,可以打開Breakpoints控制面板:菜單欄 Run -->View Breakpoints
如下圖所示:
看左側的列表分類,斷點類型大概總共六類如下表:
斷點名字 | 中文名字 | 作用 |
---|---|---|
Java Line Breakpoint | 行斷點 | 最常見的斷點,執行到這一行代碼會觸發斷點 |
Java Method Breakpoint | 方法斷點 | 斷點打在方法頭那一行,更加方便的觀察參數和返回值 |
Java Field Breakpoint | 字段斷點 | 打在某個字段聲明上,當字段被重新賦值的時候觸發斷點 |
Java Exception Breakpoint | Java 異常斷點 | 當拋出某個異常時,觸發斷點 |
Exception Breakpoint | 異常斷點 | 未知 |
Symbolic Breakpoint | 符號異常 | 未知 |
看我左邊看右邊,右邊是對每個斷點的詳細配置,以行斷點為例,其余大同小異(出了上表最后兩個):
- Enable:斷點是不是可用
- Suspend:執行到斷點的時候,程序是不是暫停到斷點
- Condition:執行這個斷點條件
- Log message to console :執行到這個斷點的時候,打印一行日志
- Evaluate and log: 執行到這個斷點時候,打印一樣自定義日志,這個日志中可以包含程序中的變量或者求值表達式(很有用,這樣可以省去一部分Log)
- Remove once hit:斷點觸發一次后就被移除了
其余的配置我也沒用過,表示不會
2. 啟動debugger
里面有幾個按鈕可以嘗試都點一下,英文也很容易理解,從下面的進程中選擇一個要attach 到debugger上,然后就可以debug這個進程了。啟動之后,等到某個斷點被觸發的時候,就出現了下面的界面。同時可以選擇調試類型,如下引自官網:
有下列調試類型可供您選擇:
Auto
如果您希望 Android Studio 自動為您要調試的代碼選擇最合適的選項,請選擇此類型。例如,如果您的項目包含任何 C 或 C++ 代碼,Android Studio 會自動使用 Hybrid 調試類型。否則,Android Studio 會使用 Java 調試類型。
Java
如果您只想調試以 Java 編寫的代碼,請選擇此類型 - Java 調試程序會忽略您在原生代碼中設置的任何斷點或監視。
Native
如果您只想使用 LLDB 來調試代碼,請選擇此類型。使用此調試類型時,Java 調試程序會話視圖不可用。默認情況下,LLDB 只檢查您的原生代碼,而會忽略 Java 代碼中的斷點。如果您也想調試 Java 代碼,則應切換到 Auto 或 Hybrid 調試類型。
Hybrid
如果您想在調試 Java 代碼與調試原生代碼之間切換,請選擇此類型。Android Studio 會將 Java 調試程序和 LLDB 都連接到您的應用進程,一個用于 Java 調試程序,一個用于 LLDB,這樣一來,您不必重新啟動應用或更改調試配置,便可同時對 Java 代碼和原生代碼中的斷點進行檢查
3. 調試工具窗口
啟動調試之后調試面板如下圖所示,看起來好復雜,全是按鈕,把鼠標懸停在按鈕上會出現這個按鈕的名字:
先看控制按鈕,再看控制面板:
1). 橫向控制按鈕
如上圖,這些都是基本的單步調試工具所具有的功能,上面很重要的是那個Evaluate Expression
通過它可以查看當前類中所有的變量的值,并且可以計算表達式的值,甚至可以運行某個函數,得到結果??梢試L試下,在輸入的時候有代碼提示,比如在輸入框輸入我們上面的求和的函數,就能直接得到運行結果。
2). 豎向控制按鈕
標號 | 名字 | 作用 |
---|---|---|
① | Rerun android debugger | 啟動或者重啟debugger |
② | resume program | 運行程序,到下一個斷點處 |
③ | pause program | 暫停程序 |
④ | stop android debugger | 停止debugger,終止調試 |
⑤ | View Breakpoints | 打開斷點設置面板,和從菜單欄Run-->view breakpoints 進入的是同一個 |
⑥ | Mute Breakpoints | 暫時停用所有的斷點 |
7 | Get Thread dump | 獲取某個進程的信息 |
⑧ | Restore Layout | 恢復原來的debugger控制面板的布局 |
⑨ | Settings | 設置在調試過程中,會顯示那些信息(可以點開看看) |
10,11,12 | 固定窗口,關閉窗口,查看幫助 |
3). 調試工具窗口(或者說窗口)
名字 | 作用 |
---|---|
Console | 控制臺,上面設置的斷點的log比如Log message to console 就打印在這里 |
Frames | 正在運行的線程的堆棧信息(堆棧幀) |
Virables | 每個線程調用棧中的變量 |
Watches | 觀察某個變量或者某個方法的執行結果(這個比較有用)通過點擊Watches面板下邊的加號可以添加要觀察的對象 |
三、最后看個簡單的例子
解讀一下上面的配置:這個斷點是一個行斷點,打在了代碼21行,目前斷點有效(enable),當斷點被觸發的時候程序會停在斷點處等待用戶操作(Suspend),這個斷點是有觸發條件的,必須在for循環中i不等于0的情況下才會觸發這個斷點(Condition i!=0
),當斷點觸發的時候會在控制臺打印一句log通知用戶,斷點被觸發(Log message to console ),并且我們自定義個log,能夠打印i+i 的值("計算下"+i+"+"+i+"="+calculate(i,i)
)。是不是真是這樣呢,可以按照上面的步驟啟動調試,然后點擊按鈕使其執行onClick方法,然后執行到這個for循環,看是否能夠打印log。
運行結果如下:
其余類型斷點,的配置和調試大同小異,可以點著玩 ̄□ ̄||
【參考文獻】