Là nhà phát triển, tất cả chúng ta đều biết rằng có những ngày chúng ta dành nhiều thời gian cho trình gỡ lỗi hơn là trong trình soạn thảo mã. Với suy nghĩ này, gần đây tôi đã có cơ hội để xem các thành viên trong nhóm Android Studio của chúng tôi có những thủ thuật và mẹo nào để tăng tốc gỡ lỗi. Tôi đã tập hợp một số điều tốt nhất mà tôi nghĩ sẽ giúp bạn tiết kiệm thời gian và dễ dàng kết hợp vào quy trình gỡ lỗi của bạn.
Mặc dù ứng dụng của bạn có thể khác nhiều so với ứng dụng trò chơi mẫu giả định mà chúng tôi đang sử dụng ở đây, nhưng các mẹo gỡ lỗi này sẽ áp dụng cho bất kỳ ứng dụng nào.
Các bài viết liên quan:
Log filtering và folding
Hãy để chúng tôi bắt đầu với một mẹo cho câu lệnh gỡ lỗi cổ điển: printf. Thực hiện trò chơi ghi lại tốc độ khung hình trên giây mỗi giây và điểm số cuối cùng của người dùng ở cuối mỗi trò chơi. Trong cửa sổ Logcat, điều này cung cấp:
Có khá nhiều thông tin trong đầu ra mà bạn có thể không quan tâm, chẳng hạn như ngày và ID chuỗi. Bạn có thể dễ dàng cấu hình những gì được hiển thị. Từ thanh công cụ logcat, hãy nhấp vào biểu tượng Cài đặt và trong hộp thoại Định cấu hình tiêu đề Logcat, bỏ chọn thông tin bạn không muốn xem nữa.
Bây giờ bạn nhận được đầu ra nhật ký rõ ràng hơn, phù hợp hơn nhiều, như thế này:
Tuy nhiên, điều này vẫn để lại nhiều lùm xùm che khuất các thông điệp về điểm số cao. Để tập trung vào những thông báo này, hãy sử dụng tìm kiếm logcat. Nhập một phần của thông báo gỡ lỗi vào Tìm kiếm để lọc cửa sổ logcat.
Nếu đây là tìm kiếm bạn sử dụng thường xuyên, bạn có thể lưu nó bằng cách thêm bộ lọc tùy chỉnh từ Chỉnh sửa cấu hình bộ lọc.
Sau đó, thêm các chi tiết của bộ lọc của bạn.
Một cách khác để giảm bớt sự lộn xộn trong việc ghi nhật ký là sử dụng tính năng đường gấp, nhóm này sẽ nhóm và thu gọn các đường giống nhau. Chọn một số văn bản từ một Mục nhật ký, nhấp chuột phải, và chọn Fold lines Như thế này.
Khi hộp thoại Bảng điều khiển mở ra, hãy nhấp vào OK và các thông báo tương tự có chứa văn bản đã chọn sẽ được thu gọn.
Nếu bạn cần xem thông tin này sau, bạn có thể nhấp vào các dòng để mở rộng chúng. Ngoài ra còn có tay cầm máng xối giúp bạn có thể mở rộng và thu gọn các đường gấp khúc.
Tiến hành debugger
Bạn thường bắt đầu một phiên gỡ lỗi bằng cách sử dụng nút Debug hoặc tùy chọn menu. Tuy nhiên, nếu bạn đã khởi động một ứng dụng bằng cách chạy nó, bạn có thể đính kèm trình gỡ lỗi vào ứng dụng đang chạy mà không cần khởi động lại. Để thực hiện việc này, hãy nhấp vào Đính kèm Trình gỡ lỗi vào Quy trình Android.
Trong hộp thoại Chọn quy trình, đánh dấu quy trình bạn muốn đính kèm trình gỡ lỗi và nhấp vào OK. Bây giờ, bạn sẽ bắt đầu đạt được các breakpoint như bình thường trong phiên gỡ lỗi.
Di chuyển các breakpoint
Nếu bạn thấy rằng bạn đã đặt một breakpoint ở một nơi không thích hợp, thay vì xóa và đặt lại breakpoint, bạn có thể kéo nó vào dòng mà bạn quan tâm. Điều này hữu ích vì nó giữ nguyên các cài đặt trên breakpoint, bao gồm cả những thứ tôi sẽ đề cập tiếp theo.
Các breakpoint có điều kiện
Bạn có thể cần phải tìm ra một lỗi liên quan đến một loại sự kiện cụ thể trong ứng dụng hoặc trò chơi của mình. Ví dụ: trong một trò chơi bạn đang phát triển, bạn có thể muốn dừng lại khi người chơi va chạm với vật thể đã sử dụng hết lượng máu cuối cùng của họ. Bạn đặt breakpoint khi va chạm nhưng bây giờ mã dừng trên mọi va chạm. Để tránh điều này, bạn có thể đặt một breakpoint có điều kiện.
Để đặt breakpoint có điều kiện, hãy nhấp chuột phải vào breakpoint và thêm điều kiện. Điều kiện có thể là bất kỳ biểu thức mã nào tương đương với Boolean. Khi mã chạm vào dòng, nếu biểu thức đánh giá là true thì breakpoint sẽ kích hoạt.
Ở đây, về mặt logic khi người chơi sắp va chạm với một vật thể, việc đặt điều kiện player.health == 1 cho phép bạn nắm bắt lần cuối cùng người chơi va chạm với vật thể trước khi lượng máu của họ giảm xuống 0.
Breakpoint phụ thuộc
Không có gì lạ khi một ứng dụng có mã có thể được kích hoạt từ nhiều đường dẫn khác nhau. Nếu bạn có một lỗi chỉ xảy ra dọc theo một đường dẫn cụ thể, việc đặt một breakpoint trong mã có thể dẫn đến rất nhiều lỗi không cần thiết. Để giải quyết vấn đề này, bạn có thể sử dụng các breakpoint phụ thuộc, chỉ kích hoạt sau khi một breakpoint được chỉ định khác bị đánh. Ví dụ: bạn có thể tạo một breakpoint chỉ được kích hoạt trong đường dẫn bạn quan tâm và sau đó sử dụng nó làm phụ thuộc, vì vậy breakpoint khác của bạn chỉ kích hoạt trong đường dẫn quan tâm.
Để đặt một breakpoint phụ thuộc, hãy nhấp chuột phải vào breakpoint thứ hai và mở menu Thêm. Trong Vô hiệu hóa cho đến khi breakpoint được nhấn, hãy chọn breakpoint bạn muốn phụ thuộc vào.
Bạn sẽ nhận thấy rằng biểu tượng breakpoint thay đổi:
Bây giờ, bạn chỉ dừng lại ở đây sau khi breakpoint trước đó được nhấn.
Bạn cũng có thể sử dụng tính năng này khi bạn có một breakpoint có điều kiện ở nơi khác và muốn tránh sao chép và dán điều kiện đó vào một vị trí mới.
Tạm dừng Thread
Nếu bạn đang gỡ lỗi một ứng dụng đa luồng, bạn sẽ nhận thấy rằng, theo mặc định, các breakpoint tạm dừng tất cả các chuỗi. Tuy nhiên, bạn có thể không muốn hành vi này. Ví dụ: có lẽ bạn muốn xác minh rằng bạn có thể chặn trên một chuỗi và ứng dụng của bạn vẫn hoạt động hoặc bạn muốn giao diện người dùng của mình tiếp tục hiển thị trong khi bạn điều tra tác vụ nền.
Để chỉ tạm dừng chuỗi hiện tại, hãy mở các tùy chọn breakpoint và chọn Chủ đề trong cài đặt Tạm dừng.
Đánh giá và ghi nhật ký
Đôi khi, thay vì dừng lại ở một breakpoint, bạn muốn xem một số thông tin liên quan đến trạng thái ứng dụng. Bạn có thể thêm printlns vào mã để thực hiện điều này. Thay vì sử dụng phương pháp này, yêu cầu biên dịch lại, bạn có thể sử dụng chính breakpoint để đánh giá và ghi nhật ký.
Để thực hiện việc này, trong các tùy chọn breakpoint, hãy tắt Tạm dừng và bật Đánh giá và ghi nhật ký.
Bây giờ bạn có thể thêm bất kỳ biểu thức mã nào và nó sẽ được đánh giá và ghi vào bảng điều khiển.
Nếu bạn chỉ muốn nhanh chóng xác minh rằng breakpoint của bạn đã được kích hoạt và không quan tâm đến các chi tiết cụ thể, hãy sử dụng thông báo “Lần truy cập breakpoint” để ghi lại rằng breakpoint đã bị tấn công. Thậm chí có một cách nhanh chóng để tạo loại breakpoint này: chỉ cần nhấn phím Shift và nhấp vào rãnh.
Tắt các breakpoint
Nếu bạn muốn tắt nhanh một breakpoint, thay vì nhấp chuột phải và bỏ chọn Đã bật, bạn có thể nhấp chuột giữa hoặc nhấn phím Alt (Tùy chọn trên máy Mac) và nhấp chuột trái, để bật và tắt breakpoint.
Nhóm breakpoint
Bạn đang khắc phục lỗi, tạo ra các breakpoint, nhưng nhận thấy mình không đạt được tiến bộ nào. Vì vậy, bạn chuyển sang làm việc với một lỗi khác. Tuy nhiên, ngay sau đó, bạn bắt đầu đạt được các điểm dừng từ lỗi đầu tiên. Việc đánh vào các breakpoint không liên quan có thể gây khó chịu và đưa bạn ra khỏi quy trình gỡ lỗi của mình.
Bạn có thể làm cho cuộc sống của mình dễ dàng hơn rất nhiều bằng cách sử dụng các nhóm breakpoint.
Khi bạn đạt đến breakpoint không mong muốn đầu tiên, hãy nhấp chuột phải và mở Thêm. Bây giờ bạn sẽ thấy danh sách tất cả các breakpoint. Chọn nhiều lần tất cả các breakpoint liên quan đến lỗi đầu tiên của bạn.
Nhấp chuột phải vào các breakpoint đã chọn và nhấp vào Di chuyển đến nhóm, sau đó nhấp vào Tạo mới. Đặt tên cho nhóm, có lẽ theo lỗi mà bạn đang xử lý. Giờ đây, bạn có thể dễ dàng bật và tắt tất cả các breakpoint chỉ bằng một cú nhấp chuột.
Ngoài ra, khi xử lý xong lỗi, bạn có thể sử dụng nhóm để xóa tất cả các breakpoint.
Drop frame
Đôi khi, khi bạn đang xem qua mã bị treo, có thể bạn vô tình bước qua một phương pháp chứ không phải vào nó. Nếu bạn đang chạy Android 10 trở lên, giờ đây, bạn có thể quay lại bằng cách nhấp vào Drop Frame trong thanh công cụ của trình gỡ lỗi.
Tính năng này kéo bạn ra khỏi phương pháp hiện tại và đưa bạn trở lại điểm trước khi nó bắt đầu, cho bạn cơ hội thứ hai để bước vào phương pháp.
Tính năng này không phải là một “cỗ máy thời gian”. Nếu bạn đang ở giữa một hàm dài và nó đã thực hiện nhiều công việc trung gian – ví dụ: sửa đổi trạng thái của lớp hiện tại – công việc đó sẽ không hoàn tác khi bạn thả khung.
Đánh dấu đối tượng
Đôi khi bạn muốn theo dõi vòng đời của một cá thể lớp cụ thể, chẳng hạn như ví dụ này, với một mục có mã băm @ 10140.
Bạn có thể muốn lôi ra một tờ giấy và viết xuống 10140, để bạn có thể xác định đối tượng khi nó xuất hiện trở lại. Tuy nhiên, cách khác, bạn có thể nhấp chuột phải vào mục, nhấp vào Đánh dấu đối tượng và gắn nhãn nó.
Giờ đây, ở bất kỳ đâu mà đối tượng được đánh dấu này xuất hiện trong bất kỳ cửa sổ gỡ lỗi nào, đối tượng đó đều được gắn nhãn và dễ tìm. Ở đây, chúng tôi đã gắn nhãn đối tượng là “myItem”:
Điều khiến điều này thậm chí còn tốt hơn cho việc theo dõi một đối tượng là khả năng nhìn thấy nó trong cửa sổ Đồng hồ, ngay cả khi bạn đang ở trong một bối cảnh hoàn toàn khác, nơi bạn không thể truy cập được mục đó. Dù bạn ở đâu, miễn là bạn đã đạt đến breakpoint, trong cửa sổ Đồng hồ, hãy thêm nhãn của bạn, theo sau là “_DebugLabel” (đừng lo lắng về việc ghi nhớ điều này, nó sẽ tự động hoàn thành).
Bây giờ, bạn có thể theo dõi hạng mục ở bất kỳ đâu trong cửa sổ Đồng hồ để xem trạng thái của nó.
Bạn cũng có thể kết hợp tính năng này với các breakpoint có điều kiện. Ví dụ: bạn có thể đặt một breakpoint, nhấp chuột phải vào nó và đặt điều kiện để kiểm tra đối tượng được gắn nhãn.
Bây giờ, thay vì bước qua nhiều breakpoint cho đến khi cá thể mục cụ thể nằm trong phạm vi, mã ngắt ở đúng vị trí dành cho bạn.
Evaluate expression
Mặc dù cửa sổ Biến và Đồng hồ hữu ích để giữ các tab trên các giá trị rõ ràng, nhưng đôi khi bạn muốn khám phá mã của mình một cách tự do hơn, đó là nơi tính năng đánh giá biểu thức xuất hiện. Khi bạn đang ở breakpoint, hãy truy cập tính năng này từ Đánh giá biểu thức trong thanh công cụ trình gỡ lỗi.
Trong phần nhập văn bản Biểu thức, hãy nhập bất kỳ biểu thức nào và nhấn Đánh giá để đánh giá biểu thức đó. Ngoài ra, nếu bạn đánh giá một đối tượng, sau khi đánh giá, bạn có thể duyệt qua đối tượng trong phần Kết quả.
Hộp thoại biểu thức đánh giá có thể mở ở chế độ một dòng. Bạn có thể dễ dàng mở rộng nó thành nhiều dòng bằng cách nhấp vào Mở rộng.
Bây giờ bạn có thể nhập các biểu thức phức tạp, nhiều dòng. Chúng có thể bao gồm các biến và câu lệnh if, trong số những biến khác.
Áp dụng các thay đổi
Khi bạn có một breakpoint có điều kiện nơi bạn đánh giá một biểu thức, ngay cả khi bạn không dừng lại ở breakpoint đó, trình gỡ lỗi vẫn phải thực hiện đánh giá. Nếu bạn đang chạy một số mã trong một vòng lặp thực sự chặt chẽ, chẳng hạn như proce hoạt hình đang sử dụng trong trò chơi, điều này có thể khiến ứng dụng bị đơ. Mặc dù các breakpoint có điều kiện rất hữu ích, nhưng đây có thể là một trường hợp khó mà bạn không thể dựa vào chúng.
Một cách để giải quyết vấn đề này là thêm biểu thức điều kiện vào mã và sử dụng biểu thức no op để bạn có thể đính kèm breakpoint.
Sau khi thực hiện xong việc này, bạn có thể quyết định khởi động lại ứng dụng của mình và nhấp vào Gỡ lỗi. Tuy nhiên, hơn thế nữa, khi chạy trên Android 8 trở lên, bạn có thể sử dụng Áp dụng thay đổi mã.
Bây giờ mã của bạn đã được vá bằng biểu thức nhúng. Tuy nhiên, bạn sẽ thấy trong cửa sổ Khung rằng phương pháp bạn đã cập nhật được đánh dấu là Đã lỗi thời.
Điều này là do mã mới đã được vá nhưng trình gỡ lỗi của bạn vẫn chỉ vào mã cũ. Bạn có thể sử dụng tính năng khung hình thả để rời khỏi phương pháp cũ và bước sang phương pháp mới.
Mặc dù chúng tôi không cần nó trong trường hợp này, nhưng có một tùy chọn thứ hai, Áp dụng Thay đổi và Khởi động lại Hoạt động. Không giống như Áp dụng thay đổi mã, tùy chọn này cũng khởi động lại hoạt động, rất hữu ích nếu bạn đã sửa đổi tài nguyên bố cục hoặc mã mà bạn đang cố gắng gỡ lỗi, chẳng hạn như trong phương pháp onCreate.
Phân tích stacktrace
Mặc dù có tất cả các mẹo và thủ thuật này, nhưng rất tiếc, có thể bạn sẽ gặp lỗi trong mã của mình và nhận được báo cáo lỗi. Khi bạn nhận được các báo cáo lỗi này, người báo cáo có thể đã gửi kèm bản sao văn bản của ngăn xếp ngoại lệ. Bạn có thể biến những thông tin này thành thông tin có ý nghĩa trong Android Studio bằng cách sử dụng menu Phân tích, Phân tích theo dõi ngăn xếp hoặc Kết xuất chuỗi.
Công cụ này cung cấp một nơi để dán dấu vết ngăn xếp, nhưng nó sẽ được tự động điền vào bất kỳ văn bản nào trong khay nhớ tạm của bạn.
Nhấp vào OK và một phiên bản có chú thích đầy đủ của dấu vết ngăn xếp được thêm vào bảng điều khiển.
Bạn có thể thấy ngay từ cơ sở mã của mình (được đánh dấu bằng màu xanh lam ở trên) so với mã mà bạn có thể không cần chú ý đến (được đánh dấu bằng màu xám). Và, bạn có thể nhấp vào các liên kết để nhanh chóng chuyển qua cơ sở mã của bạn.