本文已參與「新人創作禮」活動,一起開啟掘金創作之路。Android Studio斷點

語言: CN / TW / HK

概述 : Android studio 斷點除錯技巧分享

1 斷點簡介

1.1斷點種類

  1. 普通斷點
  2. 方法斷點
  3. 欄位斷點
  4. 條件斷點
  5. 異常斷點

1.2斷點執行方法

  • step over F6(單步跳過)
  • Step Into F5:單步執行,遇到子函式就進入並且繼續單步執行(簡而言之,進入子函式)。
  • Force step into:強制進入,在除錯的時候能進入任何方法。
  • Drop Frame:回退到被呼叫方法處. 當需要知道當前斷點的上一層呼叫源時,可以使用這個步驟;或是希望重新執行前面的程式,可以回退到前面的方法。
  • step out F7: 當單步執行到子函式內時,用step out就可以執行完子函式餘下部分,並返回到上一層函式.與Drop Frame相似,但有區別。 (1)Step Out回退到上一層呼叫方法\ (2)回退之後,原先的變數值不能回退,變數值是執行完呼叫方法後的值。\ (3)回退之後,再按F5也不會進入到getString()方法,因為已經執行完了。\ (4)F7等價於F5+F6 (5)Drop Frame執行後,再按F6還會繼續執行,而step out會直接跳到下一步。

  • Run to Cursor:跳轉到游標所在位置

1.3斷點輔助資訊

1.3.1斷點日誌

在斷點執行後,在控制檯輸出日誌。備註:不是在logcat視窗,是在Debug的Console視窗。

1.3.2斷點堆疊資訊

在斷點執行後,在控制檯輸出日誌,日誌內容是執行斷點所在程式碼的堆疊資訊。備註:堆疊資訊中不包含時間,需要看執行時間可以斷點日誌中增加.

示例: js Breakpoint reached at com.example.test2.TActivity.onResume(TActivity.java:75) at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1472) at android.app.Activity.performResume(Activity.java:8351) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:5068) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:5121) at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:190) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:105) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2613) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loop(Looper.java:219) at android.app.ActivityThread.main(ActivityThread.java:8668) at java.lang.reflect.Method.invoke(Method.java:-1) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)

1.3.3斷點執行資訊

在斷點執行後,在控制檯輸出該斷點的簡單描述日誌。\ 示例:

js Breakpoint reached at com.example.test2.TActivity.onResume(TActivity.java:75)

2 Android Studio Debug除錯功能

2.1 Android Studio選單欄Debug功能

image.png

上圖所示: 1. debug模式重新安裝執行。 應用場景:一般需要在程式啟動時就需要進入debug,例如在MyApplication, main函式等。 2. 進入Debug模式。點選之後會彈窗,然後選擇程序。示例如下: 備註:非特殊情況,一般使用這種方法進入debug。因為debug過程中,程式執行較慢,影響除錯速度,在開啟程式進入特定介面後,再執行此操作進入Deubg模式。另外,建議開發者對該功能新增快捷鍵,非常實用,可以快速進入debug模式。 快捷鍵對應功能名稱: Main menu | Run | Attach Debugger to Android Process

image.png \ 3. 結束debug模式。 備註:多數情況下會結束程序

2.2 Android StudioDebug選單圖解

image.png

  • 1:studio 底部debug選單功能按鈕
  • 2:StepOver
  • 3: Step Into
  • 4: Force Step Into
  • 5: Step Out
  • 6: Drop Frame
  • 7: Run to Cursor
  • 8: Evalute Expression 除錯視窗
  • 9:debug Console視窗(debug日誌在這裡顯示)
  • 10:Add To Watcehes
  • 11:恢復Debug除錯
  • 12:結束Deubg除錯
  • 13:斷點管理視窗
  • 14:過濾所有斷點
  • 15:獲取記憶體Deump

2.3 Breakpoints 選單

進入方法:選擇斷點,點選點鍵》More image.png

  • 1:普通斷點區域
  • 2:方法斷點區域
  • 3:異常斷點區域
  • 4:異常斷點區域
  • 5:新增斷點
  • 6:刪除斷點
  • 7:斷點開關。可關閉和開啟斷點,預設是開啟
  • 8:斷點暫停屬性開關。預設勾選,非勾選狀態下,程式執行到斷點不會停留。
  • 9:Condition視窗。新增斷點執行條件。
  • 10:執行到斷點時列印堆疊資訊
  • 11:執行到斷點時列印斷點資訊
  • 12:列印自定義日誌,日誌都在Deubg控制檯視窗顯示
  • 13:設定當前斷點在某斷點執行之後才會執行

備註:方法斷點,預設是進入和退出都會執行,這樣日誌會列印兩次。

3 Android Studio Debug功能詳解

3.1 Evalute Expression 除錯視窗

開啟後可在Evalute視窗輸入要執行的程式碼,可以得到對應的結果,單行程式碼可省略return 示例:

image.png

快捷鍵對應的功能名稱: Main menu | Run | Debugging Actions | Evaluate Expression...\ 在AS中位置如下圖

image.png

使用場景: 在debug過程中,需要得到某些函式的值,且不是一直需要,可以此功能;另外,如果已經知道某些程式執行會發生異常,可以在該視窗中執行,得到的結果是一個Exception,通過查詢這個異常的堆疊資訊來找到造成異常的原因,同時還保證了debug不會中斷,這樣就不用重新寫try catch問題程式碼。

3.2 Add To Watches

新增執行程式碼塊。在某斷點處添加了該功能,那麼每次執行到該斷點時都會的執行。

使用方法:選中要執行的程式碼段,右鍵》點選Add To Watches; 或者在Variables視窗點選加號,再手動輸入要執行的程式碼。\ image.png

image.png

使用場景:在除錯過程需要知道某個函式的執行結果或是要執行某個方法,或者需要修改某個欄位的值。\ 實踐一:進入H5Activity,需要修改url,在onCreate方法中,獲取url後,新增斷點,然後使用Add To Watches功能,新增程式碼段 url = "new url...."。這樣就可以在不修改後臺資料、不重啟、不修改程式碼的前提下快速除錯\ 實踐二:在某斷點處需要長期知道某些方法的值。

3.2 Set Value

設定值。修改某斷點執行時,在Variables視窗中某欄位的值。 備註:只有一次有效,斷點再次執行時,不會生效。 使用方法:在Variables視窗中選中要修改的欄位,點選右鍵,點選Set Value,即可修改該欄位的值。\ image.png

3.3 Resume Program 和 Pause Program

恢復debug程式和暫停debug程式 使用場景:當想暫停debug時,可使用Pause Program,它與 Mute BreakPoints 的區別是前者暫停Deubg程式,後者只是關閉斷點,但還在debug程式中。\

使用方法:

image.png

3.4 Mute Breakpionts

關閉所有斷點

image.png

3.5 增加斷點

方法一:常見增加斷點的方式是在程式碼左側單擊左鍵,新增後效果如下圖。 image.png

方法二:在Breakpionts視窗手動新增斷點。可以新增方法斷點、欄位斷點和異常斷點。 image.png

3.6 暫停斷點

預設情況下程式執行到斷點會暫停,但也可以將暫停取消。這樣程式照樣執行,同時斷點日誌、堆疊資訊可以正常列印。這樣可以通過日誌去了解程式執行情況。

3.7 斷點狀態

3.7.1 無效斷點

ine 5250 in Secure.getString() (android.provider.Settings)  No executable code found at line 5,250 in class android.provider.Settings$Secure  Suspend: thread

翻譯:在類android.provider的第5250行沒有發現可執行程式碼。設定$安全暫停:執行緒

image.png

3.7.2 斷點關閉

關閉斷點

image.png image.png

3.7.2 斷點暫停關閉

正常斷點會在程式執行到斷點時會暫停,等待開發者操作,把暫停屬性關閉,則程式執行到斷點時不會暫停。

image.png

image.png

3.8 在系統原始碼中打斷點

方法一:通過手動新增方法斷點,將系統方法新增斷點。這樣只能新增方法斷點,且影響除錯過程中執行速度。\ 方法二:使用Android Studio自帶的模擬器,模擬器的API與APP工程中compileSdkVersion 版本要一致。因為很多手機廠商定製系統或是因為手機系統版本與工程中compileSdkVersion 版本不一致,導致無法在原始碼中打斷點。提示斷點無效。

image.png

示例在使用系統方法獲取Android ID和TextView.setTextSize()方法中打斷點。

image.png

image.png

4 實踐

4.1 在系統方法中打斷點。統計APP執行過程中獲取Android Id的呼叫源和次數

應用場景:根據隱私協議要求,獲取使用者敏感資訊需要申報。APP內有較多SDK和業務程式碼獲取使用者敏感資訊。第三方(如梆梆、愛加密)採集這些資訊是通過將APP安裝在有root許可權系統的手機上,通過hook對應的系統方法,列印日誌來統計,而這個對一般開發者有一定門檻。

實現方法一:通過手動新增方法斷點,將對應的系統方法新增斷點,然後增加斷點日誌,列印執行時間和對應的TAG,同時列印斷點資訊和堆疊資訊,另外要將該斷點的暫停開關關閉,不需要暫時,讓其正常執行。

獲取Android ID API

js String ANDROID_ID = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);

image.png

4.2 APP執行過程中動態新增程式碼執行塊

應用場景:在除錯過程中,需要增加一些程式碼,重新編譯執行代價較大。可以打斷點,然後在斷點的Condition視窗增加執行程式碼塊和執行條件。相當於條件斷點中,增加了程式碼執行塊。Add To Weacth只能增加一行程式碼,並不能增加更多程式碼。 示例:在某斷點處新增程式碼塊並執行

image.png