Android 你不知道的除錯技巧(Debug操作彙總)

金燦燦發表於2020-02-28

本文通過Android Studio工具來講述你不曾知道的一些Debug小技巧。文中有許多操作,不需要死記硬背,只需瀏覽一遍,瞭解一番,增加個印象。等到要上手操作的時候,再憶起本文,回來檢視檢視。久而久之你就能熟能生巧,成為一代Debug大師!

Android Studio 版本

使用版本為3.5.3

除錯專案

除錯的專案只有一張頁面,由 RecyclerView + 底部一個Button組成。

Android 你不知道的除錯技巧(Debug操作彙總)

使用Logcat檢視日誌技巧

去除多餘資訊

為了方便舉例,我使用addOnScrollListener(...)方法來監聽RecyclerView的滑動事件,然後在onScrolled(...)方法裡,通過Log.d("recycler_view", "recycler view was Scrolled...")把資訊列印到控制檯,如下圖所示:

Android 你不知道的除錯技巧(Debug操作彙總)
大家可能注意到,上圖中有許多內容是我們不需要關心的,例如紅圈裡面的時間執行緒包名。這時我們可以點選右邊工具欄的Logcat Header圖示,來把這些資訊移除,如:

Android 你不知道的除錯技巧(Debug操作彙總)

Android 你不知道的除錯技巧(Debug操作彙總)

Android 你不知道的除錯技巧(Debug操作彙總)
我們只保留一個TAG,這樣我們Logcat介面就會變得清爽很多,看下效果:

Android 你不知道的除錯技巧(Debug操作彙總)

過濾結果

在Logcat介面的搜尋欄中,我們可以輸入自定義的TAG來過濾結果:

Android 你不知道的除錯技巧(Debug操作彙總)

但如果存在多個TAG的時候,我們應該把它們儲存起來,這樣才不僅方便我們回過頭來繼續檢視,也無須在腦中開闢塊空間把TAG名記住。來來來,一起動手來編輯一下過濾器配置:

Android 你不知道的除錯技巧(Debug操作彙總)

圖中左上角的“+”是新增,“-”是移除。

Android 你不知道的除錯技巧(Debug操作彙總)
新增完成之後,我們就不用在搜尋欄中輸入相應的TAG了,取而代之的是,直接點選右上角的過濾器,選擇我們新增進去的TAG即可。

Android 你不知道的除錯技巧(Debug操作彙總)

摺疊資訊

為了方便講解,我在監聽中的onScrollStateChanged(...)方法裡,使用同一個TAG向控制檯列印一條資訊:Log.d("recycler_view", "state:" + newState),如下圖所示:

Android 你不知道的除錯技巧(Debug操作彙總)

此時我們只想檢視有關它state的值,並不關心其他資訊。那麼我們可以選中那些多餘且不關心的子字串,右鍵它,點選Fold lines like this。這樣就為我們建立了一個過濾器

可以摺疊所有包含我們選中的子字串的字串! 留下我們關心的資訊:

Android 你不知道的除錯技巧(Debug操作彙總)

Android 你不知道的除錯技巧(Debug操作彙總)

Android 你不知道的除錯技巧(Debug操作彙總)

現在我們再回過頭看看剛才列印出來的這些Log,是不是頓時覺得眼睛輕鬆了很多!當然點選紅圈裡面的‘+’,可以隨時展開或摺疊。

Debug斷點跟蹤除錯技巧

基本使用

啟動Debug有兩種方式,一種是點選Debug,即中間的那隻小蟲子,另一種是點選Attach debugger to Android process,即靠近右邊帶箭頭的小蟲子。

Android 你不知道的除錯技巧(Debug操作彙總)

一般我推薦使用Attach debugger to Android process來進入除錯模式,它能夠在App處於執行狀態時進入除錯模式,而要是通過Debug進入除錯,它會停止應用並重啟。這樣我們還需要一路尋找回我們需要除錯的狀態,就稍微有點煩心了。

我們點選帶箭頭的小蟲子,彈出Choose Process視窗,選擇對應程式,點選‘OK‘按鈕,進入除錯模式。

現在我們可以在程式碼中打上斷點,打斷點的方法就是點選目標行程式碼行號右側的空白處,再點選一次就是取消斷點,斷點是可以上下拖動

當App在執行時,如果擊中了斷點,則會在Debug視窗中顯示斷點資訊。

Android 你不知道的除錯技巧(Debug操作彙總)

Android 你不知道的除錯技巧(Debug操作彙總)

工具欄操作按鈕

接著,來了解下Debug的操作按鈕:

斷點管理區操作按鈕:

Android 你不知道的除錯技巧(Debug操作彙總)

順序從上到下:

  • Resume Program:一是可從當前斷點移動到下一個斷點,斷點間的程式碼自動執行;二是讓App從暫停狀態恢復到執行狀態。
  • Pause Program:暫停App。
  • Stop:對於普通的JAVA專案則是退出除錯,對於Android專案則是結束App執行。
  • View Breakpoints:檢視所有斷點,並可以管理配置斷點的行為。
  • Mute Breakpoints:切換啟用或禁用所有斷點的狀態。
  • Get Thread Dump:進入執行緒Dunmp介面。

除錯區操作按鈕:

Android 你不知道的除錯技巧(Debug操作彙總)
順序從左往右:

  • Show Excution Point定位到正在被執行的斷點位置。
  • Step Over:單步執行,即前進到下一行程式碼。
  • Step Into進入呼叫方法的第一行,不能跳到類庫方法。
  • Force Step Info:與Step Into方法類似,只不過他能跳到類庫的方法裡
  • Step Out:前進到當前方法之外的下一行,可與Step Into配合使用。
  • Drop Frame:返回到方法執行的初始點(下方有演示)。
  • Run to Cursor:跳轉到游標所在處,需要當前斷點已經執行到最後一個,且游標所在的程式碼行要符合由上到下的執行順序,不能顛倒。

Drop Frame:可以用來在除錯的時候,原本想點選Step Into進入方法內部看看,卻不小心點了Step Over向下走了一行。如果除錯執行的裝置是Android10以上的版本,那麼我們可以點選Drop Frame按鈕——它的作用是可以把我們從當前方法拉出來放回方法開始前的地方。接著點選Resume Program按鈕,就相當於獲取到了一次重新開始的機會!演示如下:

Android 你不知道的除錯技巧(Debug操作彙總)

條件斷點

我們把斷點打到迴圈體裡的某行程式碼,想看看迴圈到某一次時的執行狀態。難道此時我們要不停的點Resume Program按鈕,直到跳轉到滿足我們要求的斷點嗎?

Android 你不知道的除錯技巧(Debug操作彙總)
不,當然不需要。假如我們想檢視斷點在執行到第二十次時的狀態,可以右擊這個斷點,在彈出的視窗中的Condition里加入任何布林表示式i==20(可以選擇語句的語言),點選‘Done’按鈕完成配置:

Android 你不知道的除錯技巧(Debug操作彙總)

如果條件為“true”,當程式碼命中這個條件時,那麼就會到達這個斷點!

日誌斷點

App在執行時擊中我們打上的斷點,立馬會把斷點資訊顯示在在Variables選單中,然後我們就需要在整個選單中找出我們想要的資訊

Android 你不知道的除錯技巧(Debug操作彙總)

這樣有時還蠻麻煩的,我們真正想做的是直接在程式碼中打上Log,但卻不想把Log語句在程式碼中打得到處都是,這時日誌斷點就派上用場了!

操作步驟:右擊需要打Log的斷點,在它彈出的視窗中取消選中Suspend(下面會介紹到),此時視窗會向下展開一些新內容。我們勾選Evaluate and log選項,並在其中新增上Log語句,點選‘Done’按鈕。

Android 你不知道的除錯技巧(Debug操作彙總)

現在,當執行緒遇上這個斷點的時候並不會停止,它只會計算斷點裡的Log表示式,並把它記錄到控制檯,然後繼續執行

異常斷點

想必App在執行的過程中遇到各式各樣未知性的異常導致的Crash常常令你抓狂,不過強大的Android Studio提供了異常斷點的功能。幫助我們在除錯執行的App遇到異常,能夠先快速準確的定位到產生異常的地方,而非第一時間停止App的執行。

我們點選斷點區工具欄上面的View Breakpoints按鈕,撥出斷點管理介面。然後點選‘+’,選擇Java Exception Breakpoints。如下圖所示:

Android 你不知道的除錯技巧(Debug操作彙總)

點選後撥出Enter Exception Class介面,我們在搜尋欄中填入想要監控異常的關鍵字。Java程式碼選擇NullPointerException,Kotlin程式碼選擇KotlinNullPointerException,點選‘OK’按鈕即可,如下圖所示:

Android 你不知道的除錯技巧(Debug操作彙總)

不過!!在我模擬空指標異常的時候發現,如果用Java程式碼寫的話,偵錯程式確實能監控的到異常,並能定位產生異常的程式碼。但是!!我用Kotlin寫的話,App直接Crash掉了。並未監控到異常,也沒定位到產生異常的程式碼。

不知道是我除錯姿勢有問題,還是暫時不支援Kotlin程式碼。

變數賦值

可以讓我們在除錯期間,通過更改斷點監控到變數的值,來改變App執行的結果!

具體操作如下:

首先我們在獲取資料的迴圈體裡打上斷點。如下圖所示:

Android 你不知道的除錯技巧(Debug操作彙總)

通過Debug進入除錯模式,在Variables選單中,選中我們要改變的變數,右擊它,在開啟的選項中點選Set Value...。如下圖所示:

Android 你不知道的除錯技巧(Debug操作彙總)

我們把i=1更改為i=28,此時能清楚得看到,在程式碼中顯示的變數i資訊也從i:1變成了i:28。如下圖所示:

Android 你不知道的除錯技巧(Debug操作彙總)

在迴圈中,原本變數i的值是從1到30,但我們已經把初始i的值改為了28,點選斷點區工具欄上的Resume Program按鈕,原本需要迴圈30下才執行完畢的斷點現在點3下便可完成。

現在來看看更改變數值後App的情況吧:

Android 你不知道的除錯技巧(Debug操作彙總)

Suspend 選項

在我們右擊斷點的時候,你可能留意到這的Suspend選項,如下圖所示:

Android 你不知道的除錯技巧(Debug操作彙總)

目前我們“All”與“Thread”之中選擇了“All”,意味著在當前執行執行緒遇到該斷點的時候,會停止App內的所有執行緒,這樣就會停止App整個執行狀態。

但是如果你正在處理一個多執行緒App,而你正在尋找一些特別麻煩的非同步問題,你可以試著只去暫停那個撞到斷點的執行緒。可把選中“All”改為選中“Thread”。

直到擊中某一斷點才啟用

為了方便舉例,我在示例中RecyclerView的滑動監聽裡面按鈕的點選監聽中分別打上斷點。

由於斷點被打在RecyclerView的滑動監聽裡,那麼我們手指稍微一滑動,就會立即執行該斷點。那麼在除錯的時候我想必須先擊中按鈕監聽裡面的斷點,才允許執行RecyclerView的滑動監聽裡面的斷點。

此時,Disable until breakpoint is hit功能就派上用場了。

右擊RecyclerView的滑動監聽裡斷點,在彈出的視窗裡麵點選More

Android 你不知道的除錯技巧(Debug操作彙總)

我們就會進入到斷點管理介面,在該斷點的Disable until breakpoint is hit選項中,禁用斷點,直到我們選擇的按鈕監聽裡斷點被命中為止。如下圖所示:

Android 你不知道的除錯技巧(Debug操作彙總)

現在手指滑動螢幕的時候並不會觸發RecyclerVie滑動監聽裡面的斷點,直到點選了按鈕,觸發了點選監聽裡面的斷點,才被啟用一次。意味著每次執行完該斷點,就會被禁用掉,除非再點選一次按鈕才被重新啟用。演示如下:

Android 你不知道的除錯技巧(Debug操作彙總)

禁用斷點

當已被打上的斷點,我們暫時不需要命中它的時候,我們可以把它給禁用掉,右鍵斷點,在彈出的視窗來取消勾選Enable選擇。此時斷點會變成一個空心圓。不過更方便的做法是通過“Alt + 點選”,Mac是“Opt + 點選”。這樣就能讓它在開/關的狀態下切換

Android 你不知道的除錯技巧(Debug操作彙總)

斷點組

有時候我們在執行除錯App功能的時候會遇到一些暫時不需要使用的斷點,我們又不想把它們刪掉,也許除錯下個功能可能會用上,所以只能一個一個禁掉它們。

其實,只要我們學會使用斷點組,這就方便多了!

右鍵斷點,點選視窗的More,前往斷點管理介面。我們還可以點選Debug視窗裡的斷點區工具欄中的View Breakpoint按鈕也能前往。

在該介面中,可以看到所有斷點都在上面。我們多選它們,右擊,建立一個新的組,你可以把它們起名為你正在處理Bug的名字

這裡我起名為OnScrollListener,意味著該組的斷點都來自addOnScrollListener(...)的監聽裡。如下圖所示:

Android 你不知道的除錯技巧(Debug操作彙總)

分組完畢後,你可以通過點選組的單選框來切換組內斷點開/關的狀態。當你處理完Bug後,可以選中組,並點選“-”,即可把它們全部刪掉。如下圖所示:

Android 你不知道的除錯技巧(Debug操作彙總)

Evaluate expression

系統給Variables區的變數物件提供了表示式求值的功能。在抵達斷點後,如果有變數物件。我們可以輸入任何表示式,來實時檢視表示式的計算結果。

首先,可通過點選工具欄上面的Evaluate expression按鈕,或者右鍵目的碼選擇Evaluate expression來撥出操作介面。如下圖所示:

Android 你不知道的除錯技巧(Debug操作彙總)

一般首次開啟它的時候,是單行輸入模式,我們輸入一條textList[position],點選‘Evaluate’按鈕,就能在下方Result中瀏覽物件。如下圖所示:

Android 你不知道的除錯技巧(Debug操作彙總)

如果我們想輸入更加豐富的表示式,那麼單行模式不能滿足我們的需求。點選輸入框的右上角,將單行模式擴充套件為多行。這樣,我們就能夠輸入更加豐富的表示式:

Android 你不知道的除錯技巧(Debug操作彙總)

Evaluate expression 是非常適合充當實時檢測器,它能夠讓我們清楚的觀察到當前應用的狀態。

分析堆疊軌跡

在合作開發專案中,也許我們會收到來自同事發來的一份包含呼叫棧的Bug報告,其實也就是一堆文字。我們複製Bug報告,回到Android Studio,點選工具欄上面的Analyze,然後點選Analyze Stack Trace...,我們會發現它找到了貼上板上面的內容:

Android 你不知道的除錯技巧(Debug操作彙總)

點選‘OK’按鈕後,它會對我們的呼叫棧作一個全面的註解,並顯示在控制檯中。我們點選其中的連結,就會對我們的程式碼庫進行一個快速的檢索並定位程式碼:

Android 你不知道的除錯技巧(Debug操作彙總)

總結

本篇文章大部分內容來自谷歌官方的視訊Android Studio: 除錯的技巧與心得,我推薦大家可以關注下谷歌的官方賬號。裡面有很多優質的視訊,都是由開發者本人來講解的。

希望本文能給大家在除錯App的時候提供多一條思路。

參考

感謝以下資料,讓我站在了巨人的肩膀

相關文章