使用中斷點進行偵錯

1. 事前準備

到目前為止,大多數的新手開發人員可能已經會使用記錄陳述式進行偵錯。完成單元 1 後,您將學到如何解讀堆疊追蹤和研究錯誤訊息。雖然這兩種工具都是功能強大的偵錯工具,但現代 IDE 提供更多功能,讓您的偵錯流程更有效率。

在本課程中,您將瞭解 Android Studio 整合的偵錯工具、如何暫停執行應用程式,以及一次執行單行程式碼,找出錯誤的確切來源。此外,您將學會如何使用一項稱為「Watches」的功能以及如何追蹤特定變數,而不必新增特定的記錄陳述式。

必要條件

  • 您已瞭解如何在 Android Studio 中瀏覽專案。
  • 熟悉 Kotlin 記錄功能。

課程內容

  • 如何將偵錯工具附加到運作中的應用程式。
  • 使用中斷點來暫停執行中的應用程式,逐行檢查程式碼。
  • 將條件運算式加入中斷點以節省偵錯時間。
  • 在「Watches」窗格中新增變數,以輔助偵錯。

軟硬體需求

  • 已安裝 Android Studio 的電腦。

2. 建立新專案

我們不會一開始就對複雜的大型應用程式進行偵錯,而是會從空白專案著手並介紹一些錯誤程式碼,藉此展示 Android Studio 中的偵錯工具。

建立新的 Android Studio 專案,即可開始使用。

  1. 在「Select a Project Template」(選取專案範本) 畫面中選擇「Blank Activity」(空白活動)

a949156bcfbf8a56.png

  1. 將應用程式命名為「Debugging」,接著確認語言已設為 Kotlin,其他項目則保持不變。

9863157e10628a87.png

  1. 系統將開啟一項新的 Android Studio 專案,並顯示一個名為 MainActivity.kt 的檔案。

e3ab4a557c50b9b0.png

回報錯誤

還記得單元 1 中偵錯課程的除以零範例嗎?在迴圈的最終疊代中,應用程式嘗試執行除以零時,因為不可能除以零,因此應用程式當機,並彈出 java.langArithmeticException。藉由檢查堆疊追蹤找出該錯誤並予以解決,並且使用記錄陳述式驗證該假設。

由於您已經熟悉那個範例,因此將用於示範中斷點的使用方式。中斷點會逐行處理程式碼,不必先新增記錄陳述式或重新執行應用程式。

  1. 開啟 MainActivity.kt,並將程式碼替換為以下程式碼:
package com.example.myapplication

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

public val TAG = "MainActivity"

class MainActivity : AppCompatActivity() {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)
       division()
   }

   fun division() {
       val numerator = 60
       var denominator = 4
       repeat(5) {
           Log.v(TAG, "${numerator / denominator}")
           denominator--
       }
   }

}
  1. 執行應用程式。觀察應用程式是否如預期當機。

9468226e5f4d5729.png

3. 透過中斷點進行偵錯

瞭解記錄功能後,您已學會如何有策略地放置記錄,以便識別錯誤及驗證問題是否已修正。然而,在面對並非您導入的錯誤時,我們未必能明確得知要將記錄陳述式放置在何處,或是要輸出哪些變數。通常,您只能在執行階段找到這項資訊。

fun division() {
    val numerator = 60
    var denominator = 4
    repeat(5) {
        Log.v(TAG, "${numerator / denominator}")
        denominator--
    }
}

此時,中斷點就能發揮功效。即使您已根據堆疊追蹤中的資訊大致推斷出造成錯誤的原因,您仍可在某行程式碼新增中斷點做為停止訊號。一旦觸及中斷點,系統就會暫停執行程式碼,讓您可以在執行階段使用其他偵錯工具,以便詳細瞭解實際情況並判斷問題。

附加偵錯工具

Android Studio 會在背景使用名為 Android Debug Bridge (ADB) 的工具。這項指令列工具已整合至 Android Studio,可為執行中的應用程式提供中斷點等偵錯功能。進行偵錯的工具通常稱為偵錯工具。

如要將偵錯工具用於或附加至應用程式,您無法像往常一樣依序點選「Run」(執行) >「Run」(執行) 執行應用程式,而是改為「Run」(執行) >「Debug 'app'」(對「應用程式」進行偵錯)

340a8e850b3c86d3.png

在專案中新增中斷點

請執行下列步驟,觀察中斷點的實際運作情形:

  1. 找到您希望中斷動作的行號,點選旁邊的空白以新增中斷點。行號旁邊會出現一個點,且該行程式碼會醒目顯示。

629ac33dfb3873e.png

  1. 利用「Run」(執行) >「Debug 'app'」(對「應用程式」進行偵錯) 或工具列中的 a71c8b295db5927d.png 圖示,執行附有偵錯工具的應用程式。應用程式啟動後,您會看到像這樣的畫面:

3bd9cbe69d5a0d0e.png

一旦啟動應用程式,系統會醒目顯示有效的中斷點。

928fc1194966c9.png

先前已開啟 Logcat 視窗的某個畫面底部已開啟「Debug」分頁。

447d9743c118babd.png

左側是函式清單,與堆疊追蹤中顯示的清單相同。右側是一個窗格,可讓您查看目前函式 (即 division()) 中個別變數的值。您也可以透過頂端的按鈕,在程式暫停執行期間進行瀏覽。最常用的按鈕是「Step Over」(不進入),用來執行醒目顯示的單行程式碼。

48219b96d5ab6ba6.png

請按照下列步驟操作,對程式碼進行偵錯:

  1. 到達中斷點後,第 19 行 (宣告 numerator 變數) 會醒目顯示,但尚未執行。使用「Step Over」(不進入)fbdcba647f9844c4.png 按鈕執行第 19 行。現在將醒目顯示第 20 行。

eaacf76805166461.png

  1. 在第 22 行設定中斷點。這就是發生除法的位置,也是堆疊追蹤回報例外狀況的一行。

1f18ab31dc58a1a7.png

  1. 使用「Debug」(偵錯) 視窗左側的「Resume Program」(繼續執行程式) 616d16841834ae2a.png 按鈕,前往下一個中斷點。執行 division() 函式的其餘部分。

3a9c3edc893f9720.png

  1. 請注意,執行作業在第 17 行停止,未執行該行。

aa56331ad870cd40.png

  1. 每個變數 numeratordenominator 的值會顯示在其宣告旁邊。變數值會顯示在「Variables」分頁的偵錯視窗中。

5b3515c5580ee7dd.png

  1. 再按下「Debug」(偵錯) 視窗左側的「Resume Program」(繼續執行程式) 按鈕四次。每次迴圈暫停時觀察 numeratordenominator 的值。在最後一個疊代作業中,numerator 應為 60,而 denominator 應為 0。然而將 60 除以 0 並不符合數學規則!

56ea223612b88125.png

這樣一來,您就能得知造成錯誤的確切程式碼行,並瞭解確切原因。和先前一樣,只要將程式碼重複的次數從 5 變更為 4,即可修正錯誤。

fun division() {
    val numerator = 60
    var denominator = 4
    repeat(4) {
        Log.v(TAG, "${numerator / denominator}")
        denominator--
    }
}

4. 設定中斷點條件

在上一節中,您必須逐一檢查疊代迴圈,直到分母為 0。在較為複雜的應用程式中,如果您的錯誤資訊較少,可能會很繁瑣。不過,如果您有一個假設 (例如,應用程式只有在分母為零時才會異常終止),則可以修改中斷點,限制只有在符合假設時才會觸及中斷點,這樣就不必逐一檢查迴圈疊代。

  1. 如有需要,請在重複迴圈中將 4 變更為 5,以重新回報錯誤。
repeat(4) {
    ...
}
  1. 在含有 repeat 陳述式的行上放置新的中斷點。

47fcc3aeb814a9d7.png

  1. 在紅色中斷點圖示上按一下滑鼠右鍵。選單會顯示數個選項,例如是否已啟用中斷點。停用的中斷點仍然存在,但不會在執行階段觸發。您也可以選擇新增 Kotlin 運算式,如果運算結果為 True,就會觸發中斷點。例如,如果使用 denominator > 3 運算式,則只有在初次疊代迴圈時,才會觸發中斷點。如果只想在應用程式可能除以零時觸發中斷點,請將運算式設為 denominator == 0。中斷點的選項會如下所示:

76045ef783d5389b.png

  1. 依序點選「Run」>「Debug 'app'」執行您的應用程式,並觀察是否已到達中斷點。

74ba264a6eab7db7.png

如您所見,分母已是 0。只有符合條件時才會觸發中斷點,因此您不必逐一檢查程式碼,可節省時間和精力。

153be06e8a19e61d.png

  1. 和先前一樣,您會看到錯誤是因為循環執行一行程式碼太多次所造成,此時分母設為 0。

新增 Watches

如果想在偵錯時監控特定值,並不需要在「Variables」分頁中搜尋該值,只要新增所謂的 Watches 即可監控特定變數。這些變數會顯示在偵錯窗格中。當執行暫停且該變數位於範圍內時,就會顯示在「Watches」窗格中。如此一來,處理大型專案時,就能提高偵錯效率。您可以集中追蹤所有相關變數。

  1. 在「Debug」檢視畫面中,「Variables」窗格右側會顯示另一個名為「Watches」的空白窗格。按一下左上角的加號 c97b1f6a879b0563.png 按鈕。您可能會看到顯示「New Watch」的選單選項。

4d27cc7c5222377b.png

  1. 在提供的欄位中輸入變數名稱 denominator,接著按一下 enter 鍵。
  2. 依序按一下「Run」(執行) >「Debug 'app'」(對「應用程式」進行偵錯) 重新執行應用程式,這時您會發現以下情況:遇到中斷點時,系統會在「Watches」窗格顯示分母的值。

5. 恭喜

摘要 :

  • 您可以設定暫停執行應用程式的中斷點。
  • 執行暫停時,您可以「跳過」只執行單一行程式碼。
  • 您可以設定條件陳述式,根據 Kotlin 運算式觸發中斷點。
  • Watches 可讓您在偵錯時將感興趣的變數分組。

瞭解詳情