1. 事前準備
到目前為止,大部分的開發人員一開始都很可能已經使用記錄陳述式進行偵錯。完成單元 1 後,您將學到如何解讀堆疊追蹤和研究錯誤訊息。雖然這兩種工具都是功能強大的偵錯工具,但現代 IDE 提供更多功能,讓您的偵錯流程更有效率。
在本課程中,您將瞭解 Android Studio 整合的偵錯工具、如何暫停執行應用程式,以及一次執行單一程式碼,找出錯誤的確切來源。此外,您將學會如何使用一個名為「智慧手錶」的功能及追蹤特定變數,不必新增特定的記錄陳述式。
必要條件
- 您已瞭解如何在 Android Studio 中瀏覽專案。
- 熟悉 Kotlin 記錄功能。
課程內容
- 如何將偵錯工具附加到運作中的應用程式。
- 使用中斷點來暫停執行中的應用程式,並逐一檢查程式碼。
- 將條件運算式加入中斷點以節省偵錯時間。
- 在「智慧手錶」窗格中新增變數,以輔助偵錯。
軟硬體需求
- 已安裝 Android Studio 的電腦。
2. 建立新專案
我們將從空白專案開始,先顯示一個空白專案並導入一些錯誤程式碼來示範 Android Studio 中的偵錯工具,而不是針對大型和複雜的應用程式進行偵錯。
建立新的 Android Studio 專案,即可開始使用。
- 在「Select a Project Template」畫面中選擇「Blank Activity」。
- 將應用程式命名為「Debugging」,確認語言已設為 Kotlin,其他名稱則維持不變。
- 您將會收到一個新的 Android Studio 專案,當中有一個名為
MainActivity.kt
的檔案。
回報錯誤
還記得單元 1 中偵錯課程的除以零範例嗎?在迴圈的最終疊代中,應用程式嘗試執行除以零時,因為不可能除以零,因此應用程式當機,並彈出 java.langArithmeticException
。藉由檢查堆疊追蹤找出該錯誤並予以解決,並且使用記錄陳述式驗證該假設。
由於您已經熟悉那個範例,因此將用於示範中斷點的使用方式。中斷點會逐步處理程式碼,不必先新增記錄陳述式並重新執行應用程式。
- 開啟
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--
}
}
}
- 執行應用程式。觀察應用程式是否如預期當機。
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'」進行偵錯。
在專案中新增中斷點
請按照下列步驟以出現動作中的中斷點:
- 按一下要暫停的行數旁列間的空白,即可新增中斷點。行號旁邊會出現一點,並醒目顯示線條。
- 利用「Run」>「Debug ‘app'」或工具列中的
圖示,附加執行偵錯工具的應用程式。應用程式啟動後,您會看到像這樣的畫面:
一旦啟動了應用程式,被啟用時畫面上會出現一個醒目的中斷點。
先前已開啟 Logcat 視窗的某個畫面底部已開啟「偵錯」分頁。
左側是函式清單,與堆疊追蹤中顯示的清單相同。右側是一個窗格,可讓您查看目前函式 (即 division()
) 中個別變數的值。您也可以透過畫面頂端的按鈕,前往已暫停執行的程式。最常用的按鈕是 Step Over,負責執行單一醒目顯示的程式碼行。
請按照下列步驟操作,對程式碼進行偵錯:
- 觸及中斷點後,第 19 行 (宣告
numerator
變數) 會醒目顯示,但尚未執行。使用「Step Over」按鈕執行第 19 行。現在將醒目顯示第 20 行。
- 在第 22 行設定中斷點。這就是劃分發生之處,同時也是堆疊追蹤回報例外狀況的一行。
- 使用「Debug」視窗左側的「Resume Program」
按鈕,即可前往下一個中斷點。執行
division()
函式的其餘部分。
- 請注意,第 17 行的執行作業會在執行之前停止。
- 每個變數
numerator
和denominator
的值會顯示在其宣告旁邊。變數值會顯示在「變數」分頁中的偵錯視窗中。
- 按下「Debug」視窗左側的「Resume Program」按鈕 4 次以上。每次迴圈暫停並觀察
numerator
和denominator
的值時。在最後一個疊代作業中,numerator
應為60
,而denominator
應為0
。無法將 60 除以 0!
這樣一來,您就能得知造成錯誤的確切程式碼行,並瞭解確切原因。和先前一樣,只要變更程式碼從 5
至 4
的次數,即可修正錯誤。
fun division() {
val numerator = 60
var denominator = 4
repeat(4) {
Log.v(TAG, "${numerator / denominator}")
denominator--
}
}
4. 設定中斷點條件
在上一節中,您必須逐一檢查疊代迴圈,直到分母為 0。在較為複雜的應用程式中,如果您的錯誤資訊較少,可能會很繁瑣。不過,如果您假設 (例如只有在分母為 0 時,應用程式才會當機),您可以修改中斷點,以便僅在符合上述假設情況時才觸及,而不必逐一檢查每個迴圈疊代。
- 如有需要,請在重複迴圈中將
4
變更為5
,以重新回報錯誤。
repeat(4) {
...
}
- 在
repeat
陳述式的一行上放置新的中斷點。
- 在紅色中斷點圖示上按一下滑鼠右鍵。選單會顯示數個選項,例如是否已啟用中斷點。停用的中斷點仍然存在,但不會在執行階段被觸發。您也可以選擇新增 Kotlin 運算式,如果運算結果為 True,就會觸發中斷點。例如,如果使用
denominator > 3
運算式,則只有在初次疊代迴圈時,才會觸發中斷點。如果只想在應用程式可能除以零時觸發中斷點,請將運算式設為denominator == 0
。中斷點的選項看起來會像這樣:
- 使用「Run」>「Debug 'app'」執行您的應用程式,並觀察到觸及的中斷點。
您可以看到分母已是 0 只有符合條件時,才會觸發中斷點,讓您無需花費大把時間與精力來逐一檢查程式碼。
- 和先前一樣,您看到錯誤是由迴圈執行多次,而分母設為 0 所引起的。
新增智慧手錶
如果您想要在偵錯時監控特定值,就不需要在「Variables」分頁標籤中搜尋該值。您可以新增稱為「Watches」的這類字詞,以便監控特定變數。這些變數會顯示在偵錯窗格中。當執行暫停且該變數位於範圍內時,就會顯示在「Watches」窗格中。如此一來,處理大型專案時,就能提高偵錯效率。您可以集中追蹤所有相關變數。
- 在「Debug」檢視畫面中,「Variables」窗格右側會顯示另一個稱為「Watches」的空白窗格。按一下左上角的加號
按鈕。您可能會看到顯示「New Watch」的選單選項。
- 在提供的欄位中輸入變數名稱
denominator
,接著按一下 enter 鍵。 - 依序按一下「Run」>「Debug 'app'」以重新執行應用程式,這時您會觀察到:遇到中斷點時,您會在「Watches」窗格看到分母的值。
5. 恭喜
摘要 :
- 您可以設定中斷點來暫停執行應用程式。
- 執行暫停時,您可以「跳過」只執行單一行程式碼。
- 您可以設定條件陳述式,根據 Kotlin 運算式觸發中斷點。
- 智慧手錶可讓您在偵錯時將感興趣的變數分組。