Gỡ lỗi ứng dụng

Android Studio cung cấp một trình gỡ lỗi giúp bạn thực hiện các thao tác sau và nhiều thao tác khác:

  • Chọn một thiết bị để gỡ lỗi ứng dụng của bạn.
  • Đặt các điểm ngắt trong mã Java, Kotlin và C/C++ của bạn.
  • Kiểm tra các biến và đánh giá biểu thức trong thời gian chạy.

Trang này cung cấp hướng dẫn thực hiện các thao tác cơ bản trong trình gỡ lỗi. Để tìm hiểu thêm, hãy xem cả các tài liệu gỡ lỗi của IntelliJ IDEA.

Bật tính năng gỡ lỗi

Trước khi bạn có thể bắt đầu gỡ lỗi, hãy làm như sau:

Bật tính năng gỡ lỗi trên thiết bị của bạn.
Nếu bạn đang sử dụng trình mô phỏng, thì tính năng gỡ lỗi sẽ bật theo mặc định. Tuy nhiên, đối với một thiết bị đã kết nối, bạn cần bật tính năng gỡ lỗi trong phần tuỳ chọn cho nhà phát triển trên thiết bị.
Chạy một biến thể bản dựng có thể gỡ lỗi.

Sử dụng một biến thể bản dựng bao gồm debuggable true (isDebuggable = true trong tập lệnh Kotlin) trong cấu hình bản dựng.

Thông thường, bạn có thể chọn biến thể "debug" (gỡ lỗi) mặc định có trong mọi dự án Android Studio (mặc dù biến thể này không hiện trong tệp build.gradle). Tuy nhiên, nếu xác định được các loại bản dựng mới có thể gỡ lỗi, bạn phải thêm debuggable true vào loại bản dựng:

Groovy

android {
    buildTypes {
        customDebugType {
            debuggable true
            ...
        }
    }
}

Kotlin

android {
    buildTypes {
        create("customDebugType") {
            isDebuggable = true
            ...
        }
    }
}

Thuộc tính này cũng áp dụng cho các mô-đun có mã C/C++.

Lưu ý: Ngừng sử dụng thuộc tính jniDebuggable.

Nếu ứng dụng của bạn phụ thuộc vào một mô-đun thư viện mà bạn cũng muốn gỡ lỗi, thì thư viện đó cũng phải được gói bằng debuggable true để giữ lại các biểu tượng gỡ lỗi. Để đảm bảo rằng các biến thể có thể gỡ lỗi của dự án ứng dụng nhận được biến thể có thể gỡ lỗi của mô-đun thư viện, hãy phát hành các phiên bản không mặc định của thư viện.

Bắt đầu gỡ lỗi

Bạn có thể bắt đầu một phiên gỡ lỗi như sau:

  1. Đặt điểm ngắt trong mã của ứng dụng.
  2. Trong thanh công cụ, chọn một thiết bị để gỡ lỗi ứng dụng của bạn từ trình đơn thiết bị mục tiêu.
    Trình đơn thiết bị mục tiêu.
    Hình 1. Trình đơn thiết bị mục tiêu.

    Nếu chưa định cấu hình thiết bị nào, bạn cần kết nối một thiết bị qua USB, kết nối một thiết bị qua Wi-Fi hoặc tạo một AVD để sử dụng Trình mô phỏng Android.

  3. Trong thanh công cụ, hãy nhấp vào biểu tượng Gỡ lỗi .

    Nếu ứng dụng của bạn đang chạy trên thiết bị, một hộp thoại sẽ xuất hiện hỏi xem bạn có muốn chuyển từ trạng thái Run (Chạy) sang Debug (Gỡ lỗi) hay không. Thiết bị cần phải khởi động lại để bắt đầu gỡ lỗi. Để giữ nguyên thực thể ứng dụng đang chạy, hãy nhấp vào Cancel Debug (Huỷ gỡ lỗi) và thay vào đó, hãy đính kèm trình gỡ lỗi vào một ứng dụng đang chạy. Nếu không, Android Studio sẽ tạo một APK, ký bằng khoá gỡ lỗi, cài đặt phiên bản này trên thiết bị bạn chọn rồi chạy phiên bản này.

    Nếu bạn thêm mã C và C++ vào dự án, thì Android Studio cũng chạy trình gỡ lỗi LLDB trong cửa sổ Debug (Gỡ lỗi) để gỡ lỗi mã gốc.

  4. Nếu cửa sổ Debug (Gỡ lỗi) không mở, hãy chọn View > Tool Windows > Debug (Xem > Cửa sổ công cụ > Gỡ lỗi) hoặc nhấp vào biểu tượng Gỡ lỗi trong thanh cửa sổ công cụ.

Đính kèm trình gỡ lỗi vào một ứng dụng đang chạy

Nếu ứng dụng của bạn đang chạy trên thiết bị, bạn có thể bắt đầu gỡ lỗi mà không cần khởi động lại ứng dụng như sau:

  1. Nhấp vào biểu tượng Đính kèm trình gỡ lỗi vào quy trình Android .
  2. Trong hộp thoại Chọn quy trình, hãy chọn quy trình bạn muốn đính kèm trình gỡ lỗi.
    1. Nếu đang sử dụng một trình mô phỏng hoặc thiết bị bị can thiệp hệ thống, bạn có thể chọn Show all processes (Hiển thị mọi quy trình) để xem mọi quy trình. Trên một thiết bị bị can thiệp hệ thống, thao tác này sẽ hiển thị tất cả các quy trình đang chạy trên thiết bị. Tuy nhiên, trên một thiết bị chưa bị can thiệp hệ thống, thao tác này sẽ chỉ hiển thị các quy trình có thể gỡ lỗi.
    2. Từ trình đơn Use Android Debugger Settings from (Sử dụng các chế độ cài đặt trình gỡ lỗi Android của), bạn có thể chọn một cấu hình chạy/gỡ lỗi hiện có. Đối với mã C và C++, tuỳ chọn này cho phép bạn sử dụng lại LLDB Startup Commands (Lệnh LLDB thực thi khi khởi động), LLDB Post Attach Commands (Lệnh LLDB thực thi sau khi đính kèm) và thư mục biểu tượng trong cấu hình hiện có.
    3. Nếu bạn chưa có cấu hình chạy/gỡ lỗi, hãy chọn Create New (Tạo mới). Lựa chọn này sẽ bật trình đơn Debug Type (Loại gỡ lỗi), tại đó bạn có thể chọn một loại gỡ lỗi khác. Theo mặc định, Android Studio sử dụng loại gỡ lỗi Detect Automatically (Tự động phát hiện) để chọn lựa chọn trình gỡ lỗi phù hợp nhất cho bạn, dựa trên việc dự án của bạn chứa mã Java hay mã C/C++.
  3. Nhấp vào OK.

    Cửa sổ Debug (Gỡ lỗi) sẽ xuất hiện.

Thẻ Processes (Quy trình) trong Trình khám phá thiết bị (View > Tool Windows > Device Explorer (Xem > Cửa sổ công cụ > Trình khám phá thiết bị)) cũng có danh sách các quy trình có thể gỡ lỗi. Từ đó, bạn có thể chọn một quy trình và thực hiện lệnh loại bỏ , buộc dừng hoặc đính kèm trình gỡ lỗi vào một quy trình cụ thể .

Cửa sổ gỡ lỗi

Hình 2. Cửa sổ Gỡ lỗi.

Cửa sổ gỡ lỗi được chia thành

  1. Thanh công cụ thực thi và điều hướng. Hãy xem phần Làm việc với các điểm ngắt
  2. Bộ chọn luồng
  3. Mục nhập biểu thức xem và đánh giá. Hãy xem phần Kiểm tra các biến.
  4. Màn hình ngăn xếp
  5. Ngăn biến. Hãy xem phần Kiểm tra các biến.

Lưu ý: Trình gỡ lỗi Android Studio và trình thu thập dữ liệu rác được tích hợp thoải mái. Máy ảo Android đảm bảo rằng mọi đối tượng mà trình gỡ lỗi nhận biết được sẽ không thu thập dữ liệu rác cho đến khi trình gỡ lỗi ngắt kết nối. Điều này có thể dẫn đến việc tăng dần đối tượng trong khi trình gỡ lỗi được kết nối. Ví dụ: nếu trình gỡ lỗi thấy một luồng đang chạy, thì đối tượng Thread được liên kết sẽ không được thu thập dữ liệu rác cho đến khi trình gỡ lỗi ngắt kết nối, ngay cả khi luồng đó đã kết thúc.

Thay đổi loại trình gỡ lỗi

Vì có nhiều công cụ trình gỡ lỗi cần phải gỡ lỗi mã Java/Kotlin và mã C/C++ nên trình gỡ lỗi Android Studio cho phép bạn chọn loại trình gỡ lỗi để sử dụng. Theo mặc định, Android Studio sẽ quyết định trình gỡ lỗi nào cần sử dụng dựa trên ngôn ngữ mà Android Studio phát hiện trong dự án của bạn khi dùng loại trình gỡ lỗi Detect Automatically (Tự động phát hiện).

Để chọn trình gỡ lỗi theo cách thủ công trong cấu hình gỡ lỗi, hãy nhấp vào Run > Edit Configurations (Chạy > Chỉnh sửa cấu hình). Bạn cũng có thể chọn trình gỡ lỗi trong hộp thoại xuất hiện khi nhấp vào Run > Attach debugger to Android process (Chạy > Đính kèm trình gỡ lỗi vào quy trình Android).

Sau đây là các loại gỡ lỗi hiện có:

Tự động phát hiện
Chọn loại gỡ lỗi này nếu bạn muốn Android Studio tự động chọn lựa chọn tốt nhất cho mã bạn đang gỡ lỗi. Ví dụ: nếu bạn có bất kỳ mã C hoặc C++ nào trong dự án, Android Studio sẽ tự động sử dụng loại gỡ lỗi Kép. Nếu không, Android Studio sẽ sử dụng loại gỡ lỗi Chỉ Java.
Chỉ Java
Chọn loại gỡ lỗi này nếu bạn chỉ muốn gỡ lỗi mã được viết bằng Java hoặc Kotlin. Trình gỡ lỗi Chỉ Java sẽ bỏ qua mọi điểm ngắt hoặc danh sách theo dõi bạn đã đặt trong mã gốc.
Chỉ mã gốc (chỉ dùng được với mã C/C++)
Chọn loại gỡ lỗi này nếu bạn chỉ muốn sử dụng LLDB để gỡ lỗi mã của mình. Khi sử dụng loại gỡ lỗi này, bạn sẽ không xem được phiên gỡ lỗi cho trình gỡ lỗi Java. Theo mặc định, LLDB chỉ kiểm tra mã gốc của bạn và bỏ qua các điểm ngắt trong mã Java. Nếu bạn cũng muốn gỡ lỗi mã Java, hãy chuyển sang loại gỡ lỗi Tự động phát hiện hoặc loại gỡ lỗi Kép.

Loại gỡ lỗi gốc chỉ hoạt động trên những thiết bị đáp ứng các yêu cầu sau:

  • Thiết bị hỗ trợ run-as.

    Để kiểm tra xem thiết bị có hỗ trợ run-as hay không, hãy chạy lệnh sau trên ADB shell được kết nối với thiết bị của bạn:

    run-as your-package-name pwd
    

    Thay thế your-package-name bằng tên gói của ứng dụng. Nếu thiết bị hỗ trợ run-as, lệnh sẽ trả về mà không có lỗi nào.

  • Thiết bị đã bật ptrace.

    Để kiểm tra xem ptrace đã bật hay chưa, hãy chạy lệnh sau trên ADB shell được kết nối với thiết bị của bạn:

    sysctl kernel.yama.ptrace_scope
    

    Nếu bạn bật ptrace, lệnh này sẽ in giá trị 0 hoặc lỗi unknown key. Nếu bạn không bật ptrace, lệnh này sẽ in một giá trị không phải là 0.

Loại gỡ lỗi Kép (Java + Mã gốc) – chỉ dùng được với mã C/C++
Chọn loại gỡ lỗi này nếu bạn muốn chuyển đổi giữa cửa sổ gỡ lỗi Java và mã gốc. Android Studio sẽ đính kèm cả trình gỡ lỗi Java và LLDB vào quy trình ứng dụng của bạn để bạn có thể kiểm tra các điểm ngắt trong cả mã Java và mã gốc mà không cần khởi động lại ứng dụng hoặc thay đổi cấu hình gỡ lỗi.

Trong hình 2, hãy chú ý 2 thẻ ở bên phải của tiêu đề cửa sổ Debug (Gỡ lỗi). Vì ứng dụng có cả mã Java và mã C++, nên một thẻ để gỡ lỗi mã gốc và thẻ còn lại để gỡ lỗi mã Java (được chỉ định bằng thẻ -java).

Hình 3. Thẻ để gỡ lỗi mã gốc và thẻ để gỡ lỗi mã Java.

Lưu ý: Nếu đang gỡ lỗi mã gốc được trình biên dịch tối ưu hoá, bạn có thể nhận được thông báo cảnh báo sau:
This function was compiled with optimizations enabled. Some debugger features may not be available. Khi sử dụng cờ tối ưu hoá, trình biên dịch sẽ sửa đổi mã đã biên dịch để giúp mã chạy hiệu quả hơn. Điều này có thể khiến trình gỡ lỗi báo cáo thông tin không mong muốn hoặc không chính xác vì trình gỡ lỗi khó liên kết mã đã biên dịch được tối ưu hoá với mã nguồn ban đầu. Vì lý do này, bạn nên tắt tính năng tối ưu hoá trình biên dịch trong khi gỡ lỗi mã gốc của bạn.

Sử dụng nhật ký hệ thống

Nhật ký hệ thống hiển thị các thông báo hệ thống trong khi bạn gỡ lỗi ứng dụng. Những thông báo này bao gồm thông tin từ các ứng dụng chạy trên thiết bị. Nếu bạn muốn sử dụng nhật ký hệ thống để gỡ lỗi ứng dụng của mình, hãy đảm bảo mã của bạn viết thông điệp nhật ký và in ra dấu vết ngăn xếp cho các trường hợp ngoại lệ khi ứng dụng của bạn đang trong giai đoạn phát triển.

Viết thông điệp nhật ký trong mã của bạn

Để viết thông điệp nhật ký trong mã của bạn, hãy sử dụng lớp Log. Thông điệp nhật ký giúp bạn hiểu được quy trình thực thi bằng cách thu thập kết quả gỡ lỗi hệ thống trong khi bạn tương tác với ứng dụng của mình. Thông điệp nhật ký cũng có thể cho bạn biết phần nào trong ứng dụng của bạn bị lỗi. Để biết thêm thông tin về việc ghi nhật ký, hãy xem bài viết Viết và xem nhật ký bằng Logcat.

Ví dụ sau cho thấy cách bạn có thể thêm thông điệp nhật ký để xác định xem thông tin trạng thái trước đó có hiển thị hay không khi hoạt động của bạn bắt đầu:

Kotlin

import android.util.Log
...
class MyActivity : Activity() {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        if (savedInstanceState != null) {
            Log.d(TAG, "onCreate() Restoring previous state")
            /* restore state */
        } else {
            Log.d(TAG, "onCreate() No saved state available")
            /* initialize app */
        }
        ...
    }
  ...
  companion object {
    private val TAG: String = MyActivity::class.java.simpleName
    ...
  }
}

Java

import android.util.Log;
...
public class MyActivity extends Activity {
    private static final String TAG = MyActivity.class.getSimpleName();
    ...
    @Override
    public void onCreate(Bundle savedInstanceState) {
       ...
       if (savedInstanceState != null) {
            Log.d(TAG, "onCreate() Restoring previous state");
            /* restore state */
        } else {
            Log.d(TAG, "onCreate() No saved state available");
            /* initialize app */
        }
        ...
    }
}

Trong quá trình phát triển, mã của bạn cũng có thể phát hiện các trường hợp ngoại lệ và ghi dấu vết ngăn xếp vào nhật ký hệ thống:

Kotlin

fun someOtherMethod() {
    try {
        ...
    } catch (e : SomeException) {
        Log.d(TAG, "someOtherMethod()", e)
    }
}

Java

void someOtherMethod() {
    try {
        ...
    } catch (SomeException e) {
        Log.d(TAG, "someOtherMethod()", e);
    }
}

Lưu ý: Xoá thông điệp nhật ký gỡ lỗi và lệnh gọi in dấu vết ngăn xếp khỏi mã khi bạn sẵn sàng phát hành ứng dụng. Để làm như vậy, hãy đặt cờ DEBUG và đặt thông điệp nhật ký gỡ lỗi bên trong câu lệnh có điều kiện.

Xem nhật ký hệ thống

Bạn có thể xem và lọc dữ liệu gỡ lỗi cũng như các thông báo khác của hệ thống trong cửa sổ Logcat, như minh hoạ trong hình 4. Ví dụ: bạn có thể thấy các thông báo khi việc thu thập dữ liệu rác diễn ra hoặc thông báo mà bạn thêm vào ứng dụng của mình bằng lớp Log.

Để sử dụng Logcat, hãy bắt đầu gỡ lỗi và chọn thẻ Logcat.

Hình 4. Cửa sổ Logcat có các chế độ lọc.

Để xem nội dung mô tả về Logcat và các tuỳ chọn lọc của Logcat, hãy xem bài viết Viết và xem nhật ký bằng Logcat.

Làm việc với các điểm ngắt

Android Studio hỗ trợ các điểm ngắt kích hoạt nhiều thao tác gỡ lỗi. Có một số loại điểm ngắt:

Điểm ngắt dòng
Loại phổ biến nhất là điểm ngắt dòng giúp tạm dừng việc thực thi ứng dụng của bạn trên một dòng mã được chỉ định. Trong khi tạm dừng, bạn có thể kiểm tra biến, đánh giá biểu thức, sau đó tiếp tục thực thi từng dòng để xác định nguyên nhân gây ra lỗi thời gian chạy.
Điểm ngắt phương thức
Điểm ngắt phương thức sẽ tạm dừng việc thực thi ứng dụng của bạn khi ứng dụng vào hoặc thoát khỏi một phương thức cụ thể. Trong khi tạm dừng, bạn có thể kiểm tra biến, đánh giá biểu thức, sau đó tiếp tục thực thi từng dòng để xác định nguyên nhân gây ra lỗi thời gian chạy. Khi bạn đặt điểm ngắt trong hàm có khả năng kết hợp, trình gỡ lỗi sẽ liệt kê các tham số của thành phần kết hợp và trạng thái của chúng để giúp xác định những thay đổi có thể đã dẫn đến việc kết hợp lại đó.
Điểm ngắt trường
Điểm ngắt trường sẽ tạm dừng việc thực thi ứng dụng khi ứng dụng đọc hoặc ghi vào một trường cụ thể.
Điểm ngắt ngoại lệ
Điểm ngắt ngoại lệ sẽ tạm dừng việc thực thi ứng dụng của bạn khi một ngoại lệ được gửi.

Bạn có thể đặt các điểm ngắt có điều kiện chỉ tạm ngưng việc thực thi nếu đáp ứng các điều kiện cụ thể. Bạn cũng có thể đặt điểm ngắt ghi nhật ký cho Logcat mà không cần tạm ngưng việc thực thi. Việc này có thể giúp bạn tránh làm hỏng mã bằng các câu lệnh nhật ký.

Để thêm điểm ngắt dòng, hãy tiến hành như sau:

  1. Tìm dòng mã bạn muốn tạm dừng việc thực thi.
  2. Nhấp vào rãnh bên trái dọc theo dòng mã đó hoặc đặt con nháy trên dòng và nhấn tổ hợp phím Control + F8 (trên macOS, nhấn tổ hợp phím Command + F8).
  3. Nếu ứng dụng của bạn đang chạy, hãy nhấp vào biểu tượng Đính kèm trình gỡ lỗi vào quy trình Android . Nếu không, để bắt đầu gỡ lỗi, hãy nhấp vào biểu tượng Gỡ lỗi .

Một dấu chấm màu đỏ sẽ xuất hiện bên cạnh dòng khi bạn đặt một điểm ngắt, như minh hoạ trong hình 5.

Hình 5. Một dấu chấm màu đỏ sẽ xuất hiện bên cạnh dòng khi bạn đặt một điểm ngắt.

Khi việc thực thi mã của bạn đến điểm ngắt, Android Studio sẽ tạm dừng việc thực thi ứng dụng của bạn.

Để xác định trạng thái của ứng dụng, hãy dùng các công cụ trong thẻ Debugger (Trình gỡ lỗi):

  • Để kiểm tra cây đối tượng cho một biến, hãy mở rộng cây đối tượng trong khung hiển thị Variables (Biến). Nếu khung hiển thị Variables (Biến) không hiện lên, hãy nhấp vào biểu tượng Cài đặt bố cục và đảm bảo rằng variables (biến) được chọn.

  • Để chuyển đến dòng tiếp theo trong mã mà không vào phương thức, hãy nhấp vào biểu tượng Bước qua .

  • Để chuyển đến dòng đầu tiên trong lệnh gọi phương thức, hãy nhấp vào biểu tượng Bước vào .

  • Để chuyển đến dòng tiếp theo bên ngoài phương thức hiện tại, hãy nhấp vào biểu tượng Bước ra .

  • Để tiếp tục chạy ứng dụng như bình thường, hãy nhấp vào biểu tượng Tiếp tục chương trình .

Nếu dự án của bạn sử dụng bất kỳ mã gốc nào thì theo mặc định, loại gỡ lỗi Tự động phát hiện sẽ đính kèm cả trình gỡ lỗi Java và LLDB vào ứng dụng của bạn dưới dạng 2 quy trình riêng biệt. Nhờ vậy, bạn có thể chuyển đổi giữa việc kiểm tra các điểm ngắt trong mã Java và C/C++ mà không cần khởi động lại ứng dụng hoặc thay đổi chế độ cài đặt.

Lưu ý: Để Android Studio phát hiện điểm ngắt trong mã C hoặc C++, bạn cần sử dụng loại gỡ lỗi hỗ trợ LLDB, chẳng hạn như Detect Automatically (Tự động phát hiện), Native (Mã gốc) hoặc Dual (Kép). Bạn có thể thay đổi loại gỡ lỗi mà Android Studio sử dụng bằng cách chỉnh sửa cấu hình gỡ lỗi. Để tìm hiểu thêm về nhiều loại gỡ lỗi, hãy đọc phần cho biết cách sử dụng các loại gỡ lỗi khác.

Khi Android Studio triển khai ứng dụng của bạn trên thiết bị mục tiêu, cửa sổ Debug (Gỡ lỗi) sẽ mở ra cùng với một thẻ hoặc khung hiển thị phiên gỡ lỗi cho từng quy trình gỡ lỗi, như minh hoạ trong hình 6.

Hình 6. Gỡ lỗi mã gốc bằng LLDB.
  1. Android Studio chuyển sang thẻ <your-module> khi trình gỡ lỗi LLDB gặp phải điểm ngắt trong mã C/C++ của bạn. Các ngăn Frames (Khung), Variables (Biến) và Watches (Danh sách theo dõi) cũng có sẵn và hoạt động giống như khi bạn gỡ lỗi mã Java.

    Mặc dù ngăn Threads (Chuỗi) không hiển thị trong khung hiển thị phiên LLDB, nhưng bạn có thể truy cập vào các quy trình ứng dụng bằng cách dùng danh sách trong ngăn Frames (Khung). Tìm hiểu thêm về các ngăn này trong phần cho biết cách gỡ lỗi khung cửa sổkiểm tra biến.

    Lưu ý: Trong khi kiểm tra một điểm ngắt trong mã gốc của bạn, hệ thống Android sẽ tạm ngưng máy ảo chạy mã byte Java của ứng dụng. Điều này có nghĩa là bạn không thể tương tác với trình gỡ lỗi Java hoặc truy xuất bất kỳ thông tin trạng thái nào từ phiên của trình gỡ lỗi Java trong quá trình kiểm tra điểm ngắt trong mã gốc.

  2. Android Studio chuyển sang thẻ <your-module>-java khi trình gỡ lỗi Java gặp một điểm ngắt trong mã Java hoặc Kotlin.
  3. Khi gỡ lỗi bằng LLDB, bạn có thể sử dụng thiết bị đầu cuối LLDB trong khung hiển thị phiên LLDB để chuyển các tuỳ chọn dòng lệnh tới LLDB. Nếu có một số lệnh mà bạn muốn LLDB thực thi mỗi khi bắt đầu gỡ lỗi ứng dụng, ngay trước hoặc ngay sau khi trình gỡ lỗi đính kèm vào quy trình ứng dụng, bạn có thể thêm các lệnh đó vào cấu hình gỡ lỗi.

Trong khi gỡ lỗi mã C/C++, bạn cũng có thể đặt các loại điểm ngắt đặc biệt, gọi là điểm theo dõi, để tạm ngưng quy trình dùng ứng dụng khi ứng dụng đó tương tác với một khối bộ nhớ cụ thể. Để tìm hiểu thêm, hãy đọc phần cách thêm điểm theo dõi.

Xem và định cấu hình điểm ngắt

Để xem mọi điểm ngắt và định cấu hình các chế độ cài đặt về điểm ngắt, hãy nhấp vào biểu tượng Xem điểm ngắt trong cửa sổ Debug (Gỡ lỗi). Cửa sổ Breakpoints (Điểm ngắt) sẽ xuất hiện, như minh hoạ trong hình 7.

Hình 7. Cửa sổ Breakpoints (Điểm ngắt) liệt kê mọi điểm ngắt hiện tại và có các chế độ cài đặt hành vi cho từng điểm ngắt.

Cửa sổ Breakpoints (Điểm ngắt) cho phép bạn bật hoặc tắt từng điểm ngắt trong danh sách ở ngăn. Nếu bạn tắt điểm ngắt, Android Studio sẽ không tạm dừng ứng dụng của bạn khi ứng dụng gặp điểm ngắt đó.

Chọn một điểm ngắt trong danh sách để định cấu hình các chế độ cài đặt. Trước tiên, bạn có thể định cấu hình để tắt một điểm ngắt và yêu cầu hệ thống bật điểm ngắt đó sau khi đến một điểm ngắt khác. Bạn cũng có thể định cấu hình xem có tắt điểm ngắt sau khi hệ thống đến điểm ngắt đó không. Để đặt điểm ngắt cho bất kỳ trường hợp ngoại lệ nào, hãy chọn Exception Breakpoints (Điểm ngắt ngoại lệ) trong danh sách các điểm ngắt.

Để tạm thời tắt tất cả các điểm ngắt, hãy nhấp vào biểu tượng Ẩn điểm ngắt trong cửa sổ Gỡ lỗi. Nhấp lần nữa để bật lại.

Gỡ lỗi khung cửa sổ

Trong cửa sổ Debugger (Trình gỡ lỗi), ngăn Frames (Khung) cho phép bạn kiểm tra khung ngăn xếp khiến điểm ngắt hiện tại bị ảnh hưởng. Với thao tác này, bạn có thể điều hướng và kiểm tra khung ngăn xếp, cũng như kiểm tra danh sách các luồng trong ứng dụng Android.

Để chọn một luồng, hãy sử dụng trình đơn bộ chọn luồng và xem khung ngăn xếp của luồng đó. Nhấp vào các phần tử trong khung để mở nguồn trong trình chỉnh sửa. Bạn cũng có thể tuỳ chỉnh bản trình bày luồng và xuất khung ngăn xếp như đã thảo luận trong hướng dẫn Kiểm tra khung.

Kiểm tra biến

Trong cửa sổ Debugger (Trình gỡ lỗi), ngăn Variables (Biến) cho phép bạn kiểm tra các biến khi hệ thống dừng ứng dụng của bạn trên một điểm ngắt và bạn chọn một khung từ ngăn Frames (Khung). Ngăn Variables (Biến) cũng cho phép bạn đánh giá các biểu thức đặc biệt bằng cách dùng các phương thức tĩnh và/hoặc biến có sẵn trong khung đã chọn.

Để thêm biểu thức vào cây đối tượng (trong khi ứng dụng đang được gỡ lỗi), hãy làm như sau:

Hình 8. Hộp mục nhập biểu thức và cây đối tượng trong cửa sổ Gỡ lỗi.
  1. Nhập biểu thức để theo dõi hoặc hiển thị
  2. Nhấp vào Add to watches (Thêm vào danh sách theo dõi) hoặc nhấn Enter để đánh giá biểu thức một lần.

Ngoài ra, nếu cây đối tượng chứa biểu thức bạn muốn theo dõi, thì bạn có thể kéo biểu thức đó lên đầu cây để thêm biểu thức đó làm biểu thức được theo dõi.

Biểu thức được theo dõi sẽ cập nhật khi điểm ngắt được nhấn hoặc khi bạn duyệt qua mã của mình.

Biểu thức đã đánh giá sẽ vẫn hiển thị ở đầu cây đối tượng cho đến khi bạn đánh giá một biểu thức khác theo cách thủ công hoặc duyệt qua mã của bạn.

Để xoá biểu thức đã theo dõi khỏi cây đối tượng, hãy nhấp chuột phải vào biểu thức đó rồi nhấp vào Remove Watch (Xoá biểu thức theo dõi).

Thêm điểm theo dõi

Trong khi gỡ lỗi mã C/C++, bạn có thể đặt các loại điểm ngắt đặc biệt, gọi là điểm theo dõi, có thể tạm ngưng quá trình xử lý ứng dụng của bạn khi ứng dụng đó tương tác với một khối bộ nhớ cụ thể. Ví dụ: nếu bạn đặt hai con trỏ vào một khối bộ nhớ và gán một điểm theo dõi cho bộ nhớ đó, hãy sử dụng con trỏ để truy cập khối bộ nhớ đó và kích hoạt điểm theo dõi.

Trong Android Studio, bạn có thể tạo điểm theo dõi trong thời gian chạy bằng cách chọn một biến cụ thể, nhưng LLDB chỉ gán điểm theo dõi cho khối bộ nhớ mà hệ thống phân bổ cho biến đó, chứ không phải cho chính biến. Hành động này khác với việc thêm một biến vào ngăn Watches (Danh sách theo dõi), cho phép bạn quan sát giá trị của một biến nhưng không cho phép bạn tạm ngưng quy trình ứng dụng khi hệ thống sẽ đọc hoặc thay đổi giá trị của bộ nhớ trong bộ nhớ.

Lưu ý: Khi ứng dụng của bạn thoát khỏi một hàm và hệ thống loại bỏ các biến cục bộ của ứng dụng đó khỏi bộ nhớ, thì bạn cần phải gán lại mọi điểm theo dõi mà bạn đã tạo cho các biến đó.

Để đặt điểm xem, bạn phải đáp ứng các yêu cầu sau:

  • Trình mô phỏng hoặc thiết bị thực mục tiêu của bạn sử dụng CPU x86 hoặc x86_64. Nếu thiết bị của bạn sử dụng CPU ARM, thì bạn phải căn chỉnh ranh giới địa chỉ của biến trong bộ nhớ thành 4 byte đối với bộ xử lý 32 bit hoặc 8 byte đối với bộ xử lý 64 bit. Để điều chỉnh một biến trong mã gốc, hãy chỉ định __attribute__((aligned(num_bytes))) trong quá trình giảm tốc cho biến, như minh hoạ bên dưới:
    // For a 64-bit ARM processor
    int my_counter __attribute__((aligned(8)));
    
  • Bạn đã chỉ định 3 điểm theo dõi hoặc ít hơn. Android Studio chỉ hỗ trợ tối đa 4 điểm theo dõi trên những thiết bị đích x86 hoặc x86_64. Các thiết bị khác có thể hỗ trợ ít điểm theo dõi hơn.

Lưu ý: Khi gỡ lỗi ứng dụng bằng các ABI ARM 32 bit, việc thêm điểm theo dõi hoặc di chuột qua các biến bên trong mã để điều tra giá trị của các biến đó có thể gây ra sự cố. Để khắc phục, vui lòng gỡ lỗi bằng cách sử dụng tệp nhị phân ARM 64 bit, x86 hoặc x86_64. Vấn đề này sẽ được khắc phục trong bản phát hành Android Studio sắp tới.

Nếu đáp ứng các yêu cầu nêu trên, bạn có thể thêm điểm theo dõi như sau:

  1. Trong khi ứng dụng của bạn bị tạm ngưng trên một điểm ngắt, hãy chuyển đến ngăn Variables (Biến) trong khung hiển thị phiên LLDB của bạn.
  2. Nhấp chuột phải vào một biến chiếm khối bộ nhớ mà bạn muốn theo dõi rồi chọn Add Watchpoint (Thêm điểm theo dõi).

    Hình 9. Thêm một điểm theo dõi vào một biến trong bộ nhớ.
  3. Một hộp thoại định cấu hình điểm theo dõi sẽ xuất hiện, như minh hoạ trong hình 9.

    Định cấu hình điểm theo dõi với các tuỳ chọn sau:

    • Enabled (Bật): Bỏ chọn tuỳ chọn này nếu muốn Android Studio bỏ qua điểm theo dõi cho đến khi bạn thay đổi chế độ cài đặt. Android Studio lưu điểm theo dõi của bạn để bạn có thể truy cập vào điểm này sau.
    • Suspend (Tạm ngưng): Theo mặc định, hệ thống Android sẽ tạm ngưng quy trình ứng dụng của bạn khi truy cập một khối bộ nhớ mà bạn chỉ định cho một điểm theo dõi. Bỏ chọn tuỳ chọn này nếu bạn không muốn hành vi này. Khi đó, bạn sẽ có thêm các tuỳ chọn để tuỳ chỉnh hành vi khi hệ thống tương tác với điểm theo dõi của bạn: Log message to console (Ghi nhật ký thông báo vào bảng điều khiển) và Remove when hit (Xoá khi đến).
    • Access Type (Loại truy cập): Chọn xem ứng dụng của bạn có nên kích hoạt điểm theo dõi của bạn khi cố gắng Read (Đọc) hoặc Write (Ghi) vào khối bộ nhớ mà hệ thống phân bổ cho biến không. Để kích hoạt điểm theo dõi của bạn trên một lượt đọc hoặc ghi, hãy chọn Any (Bất kỳ).
  4. Nhấp vào Done (Xong).

Để xem tất cả các điểm theo dõi của bạn và định cấu hình các chế độ cài đặt điểm theo dõi, hãy nhấp vào biểu tượng Xem điểm ngắt trong cửa sổ Debug (Gỡ lỗi). Hộp thoại Breakpoints (Điểm ngắt) xuất hiện, như minh hoạ trong hình 10.

Hình 10. Hộp thoại Breakpoints (Điểm ngắt) liệt kê các điểm theo dõi hiện tại của bạn và bao gồm các chế độ cài đặt hành vi cho từng điểm.

Sau khi bạn thêm điểm theo dõi, hãy nhấp vào biểu tượng Tiếp tục chương trình trong cửa sổ Debug (Gỡ lỗi) để tiếp tục quy trình của ứng dụng. Theo mặc định, nếu ứng dụng của bạn cố gắng truy cập một khối bộ nhớ mà bạn đã đặt điểm theo dõi, thì hệ thống Android sẽ tạm ngưng quy trình ứng dụng của bạn và biểu tượng điểm theo dõi xuất hiện bên cạnh dòng mã ứng dụng của bạn đã thực thi gần đây nhất, như minh hoạ trong hình 11.

Hình 11. Android Studio cho biết dòng mã mà ứng dụng của bạn thực thi ngay trước khi kích hoạt điểm theo dõi.

Xem và thay đổi định dạng hiển thị giá trị tài nguyên

Ở chế độ gỡ lỗi, bạn có thể xem các giá trị tài nguyên và chọn một định dạng hiển thị khác cho các biến trong mã Java hoặc Kotlin. Khi thẻ Variables (Biến) hiển thị và một khung đã chọn, hãy làm như sau:

  1. Trong danh sách Variables (Biến), hãy nhấp chuột phải vào vị trí bất kỳ trên một dòng tài nguyên để hiển thị danh sách.
  2. Trong danh sách, hãy chọn View as (Xem dưới dạng) rồi chọn định dạng bạn muốn sử dụng.

    Các định dạng có sẵn phụ thuộc vào loại dữ liệu của tài nguyên mà bạn chọn. Bạn có thể thấy một hoặc nhiều tuỳ chọn sau đây:

    • Class (Loại): Hiển thị định nghĩa loại.
    • toString: Định dạng chuỗi hiển thị.
    • Object (Đối tượng): Hiển thị định nghĩa đối tượng (thực thể của một loại).
    • Array (Mảng): Hiển thị ở định dạng mảng.
    • Timestamp (Dấu thời gian): Hiển thị ngày và giờ như sau: yyyy-mm-dd hh:mm:ss.
    • Auto (Tự động): Android Studio sẽ chọn định dạng phù hợp nhất tuỳ vào loại dữ liệu.
    • Binary (Nhị phân): Hiển thị giá trị nhị phân bằng cách sử dụng số không và số nhị phân.
    • MeasureSpec: Giá trị được chuyển từ đơn vị gốc đến thư mục con đã chọn. Xem MeasureSpec.
    • Hex (Thập lục phân): Hiển thị dưới dạng giá trị thập lục phân.
    • Primitive (Gốc): Hiển thị dưới dạng giá trị số bằng loại dữ liệu gốc.
    • Integer (Số nguyên): Hiển thị một giá trị số thuộc loại Integer.

Để tạo định dạng tuỳ chỉnh, hãy làm theo các bước sau:

  1. Nhấp chuột phải vào giá trị tài nguyên.
  2. Chọn View as (Xem dưới dạng).
  3. Chọn Tạo.
  4. Hộp thoại Java Data Type Renderers (Trình hiển thị loại dữ liệu Java) sẽ xuất hiện. Hãy làm theo hướng dẫn tại Trình kết xuất loại dữ liệu Java.