Gỡ lỗi ANR

Việc giải quyết ANR trong trò chơi Unity là một quy trình có hệ thống:

Hình 1. Các bước giải quyết lỗi ANR trong trò chơi Unity.

Tích hợp dịch vụ báo cáo

Các dịch vụ báo cáo như Android vitals, Firebase CrashlyticsBacktrace (một đối tác được chứng nhận của Unity) cung cấp tính năng ghi nhật ký và phân tích lỗi cho trò chơi của bạn trên quy mô lớn. Tích hợp SDK dịch vụ báo cáo vào trò chơi ngay trong chu kỳ phát triển. Hãy phân tích xem dịch vụ báo cáo nào phù hợp nhất với nhu cầu và ngân sách trò chơi của bạn.

Các dịch vụ báo cáo khác nhau có những cách khác nhau để ghi lại lỗi ANR. Cung cấp dịch vụ báo cáo thứ hai để tăng cơ hội nhận được dữ liệu hợp lệ nhằm hỗ trợ bạn cho quyết định khắc phục lỗi ANR.

Việc tích hợp các SDK báo cáo không ảnh hưởng đến hiệu suất của trò chơi hoặc kích thước tệp APK.

Phân tích các ký hiệu

Phân tích các báo cáo từ dịch vụ báo cáo của bạn và kiểm tra xem dấu vết ngăn xếp có ở định dạng mà con người có thể đọc được hay không. Hãy xem phần Thay thế sự cố và lỗi ứng dụng không phản hồi (ANR) trên Android bằng biểu tượng cho các trò chơi Unity để biết thêm thông tin.

Hình 2. Crashlytics cho thấy mã bản dựng và thiếu ký hiệu libil2cpp.so.

Cách kiểm tra mã bản dựng biểu tượng

Nếu hệ thống báo cáo cho thấy mã bản dựng bị thiếu nhưng biểu tượng bản dựng vẫn tồn tại trong bộ nhớ của máy xây dựng, thì bạn có thể kiểm tra mã bản dựng của các biểu tượng đó rồi tải lên dịch vụ báo cáo. Nếu không, bạn cần phải tạo một bản dựng mới để tải các tệp biểu tượng lên.

Trên Windows hoặc macOS:

  1. Chuyển đến thư mục biểu tượng dựa trên phần phụ trợ tập lệnh (xem phần Độ phân giải:)
    1. Hãy sử dụng lệnh sau (trên Windows, hãy sử dụng Cygwin để chạy tiện ích readelf)
    2. Không bắt buộc phải sử dụng grep để lọc đầu ra văn bản
    3. Tìm mã bản dựng
readelf -n libil2cpp.so | grep 'Build ID'
Build ID: b42473fb7449e44e0182dd1f580c99bab0cd8a95

Kiểm tra mã trò chơi

Khi dấu vết ngăn xếp cho thấy một hàm trong thư viện libil2cpp.so, lỗi đã xảy ra trong mã C#, mã này được chuyển đổi sang C++. Thư viện libil2cpp.so không chỉ có mã trò chơi mà còn có trình bổ trợ và gói.

Tên tệp C++ theo tên tập hợp được xác định trong dự án Unity. Nếu không, tên tệp sẽ có tên mặc định là hội-C#. Ví dụ: hình 3 cho thấy lỗi trên tệp Game.cpp (được đánh dấu bằng màu xanh dương), đây là tên được xác định trong tệp Định nghĩa lắp ráp. Logger là tên lớp (được đánh dấu bằng màu đỏ) trong tập lệnh C#, theo sau là tên hàm (được đánh dấu bằng màu xanh lục). Cuối cùng là tên đầy đủ mà bộ chuyển đổi IL2CPP đã tạo (được đánh dấu bằng màu cam).

Hình 3. Kiểm thử ngăn xếp lệnh gọi dự án từ Backtrace.

Kiểm tra mã trò chơi của bạn bằng cách làm như sau:

  • Kiểm tra dự án C# để tìm bất kỳ mã đáng ngờ nào. Thông thường, các trường hợp ngoại lệ chưa được xử lý của C# sẽ không gây ra sự cố ANR hoặc sự cố ứng dụng. Mặc dù vậy, hãy đảm bảo mã chạy đúng cách trong nhiều tình huống. Kiểm tra xem mã có sử dụng mô-đun công cụ của bên thứ ba hay không, đồng thời phân tích xem bản phát hành gần đây có gây ra lỗi hay không. Ngoài ra, hãy xem lại xem gần đây bạn đã cập nhật Unity hay chưa, hay lỗi chỉ xảy ra trên các thiết bị cụ thể.
  • Xuất trò chơi dưới dạng một dự án Android Studio. Khi có toàn quyền truy cập vào mã nguồn C# đã chuyển đổi của trò chơi, bạn có thể tìm được hàm gây ra lỗi ANR. Mã C++ trông rất khác với mã C# và quá trình chuyển đổi mã hiếm khi gặp vấn đề. Nếu bạn tìm thấy nội dung nào đó, hãy gửi phiếu yêu cầu hỗ trợ đến Unity.
  • Xem lại mã nguồn trò chơi và đảm bảo rằng mọi logic chạy trong các lệnh gọi lại OnApplicationFocus()OnApplicationPause() đều được dọn dẹp một cách thích hợp.
    • Công cụ Unity có thời gian chờ để tạm dừng thực thi. Việc khối lượng công việc quá mức trên các lệnh gọi lại này có thể gây ra lỗi ANR.
    • Thêm nhật ký hoặc breadcrumb vào các phần của mã để cải thiện khả năng phân tích dữ liệu.
  • Sử dụng Unity Profiler (Trình phân tích tài nguyên Unity) để kiểm tra hiệu suất của trò chơi. Lập hồ sơ ứng dụng cũng có thể là một cách hay để giúp xác định nút thắt cổ chai có thể gây ra lỗi ANR.
  • Một cách hay để xác định các hoạt động I/O kéo dài trên luồng chính là sử dụng chế độ nghiêm ngặt.
  • Phân tích Android Vitals hoặc một nhật ký dịch vụ báo cáo khác và kiểm tra các phiên bản phát hành của trò chơi mà lỗi đang xảy ra nhiều nhất. Xem lại mã nguồn trong nhật ký quản lý phiên bản và so sánh những thay đổi về mã giữa các bản phát hành. Nếu bạn thấy điều gì đó đáng ngờ, hãy thử nghiệm từng thay đổi hoặc cách khắc phục tiềm năng riêng lẻ.
  • Kiểm tra nhật ký báo cáo lỗi ANR trên Google Play để biết những thiết bị và phiên bản Android gặp nhiều lỗi ANR nhất. Nếu thiết bị hoặc phiên bản đã lỗi thời, thì bạn có thể yên tâm bỏ qua những thiết bị hoặc phiên bản đó nếu việc đó không ảnh hưởng đến khả năng sinh lời của trò chơi. Hãy nghiên cứu kỹ dữ liệu vì một nhóm người dùng cụ thể sẽ không thể chơi trò chơi của bạn nữa. Để biết thêm thông tin, hãy xem Trang tổng quan về hoạt động phân phối.
  • Xem lại mã nguồn của trò chơi để đảm bảo bạn không gọi bất kỳ mã nào có thể gây ra sự cố, chẳng hạn như finish (kết thúc) có thể mang tính phá hoại nếu không được sử dụng đúng cách. Xem Hướng dẫn cho nhà phát triển Android để tìm hiểu thêm về cách phát triển Android.
  • Sau khi xem xét dữ liệu và xuất bản dựng trò chơi sang Android Studio, bạn đang xử lý mã C và C++. Vì vậy, bạn có thể khai thác tối đa các công cụ ngoài các giải pháp tiêu chuẩn của Unity, chẳng hạn như Trình phân tích bộ nhớ Android, Trình phân tích CPU Androidperfetto.

Mã công cụ Unity

Để biết liệu lỗi ANR có đang xảy ra ở phía công cụ Unity hay không, hãy kiểm tra để tìm libUnity.so hoặc libMain.so trong dấu vết ngăn xếp. Nếu bạn tìm thấy chúng, hãy thực hiện các bước sau:

  • Trước tiên, hãy tìm kiếm trên các kênh cộng đồng (Diễn đàn Unity, Các thảo luận về Unity, Stackoverflow).
  • Nếu bạn không tìm thấy lỗi nào, hãy gửi lỗi để giải quyết vấn đề. Cung cấp dấu vết ngăn xếp được thay thế bằng biểu tượng để các kỹ sư của công cụ có thể hiểu rõ hơn và giải quyết lỗi.
  • Kiểm tra xem Unity LTS mới nhất có cải thiện được các vấn đề của bạn hay không. Nếu vậy, hãy nâng cấp trò chơi của bạn để sử dụng phiên bản đó. (Giải pháp này có thể chỉ áp dụng cho một số nhà phát triển.)
  • Nếu mã của bạn sử dụng một Activity tuỳ chỉnh thay vì mặc định, hãy xem lại mã Java để đảm bảo hoạt động không gây ra bất kỳ vấn đề nào.

SDK bên thứ ba

  • Kiểm tra để đảm bảo rằng tất cả thư viện của bên thứ ba đều là phiên bản mới nhất và không có báo cáo về sự cố hoặc lỗi ANR cho phiên bản Android mới nhất.
  • Truy cập vào Diễn đàn Unity để xem liệu có lỗi nào đã được khắc phục trong phiên bản mới hơn hay không hoặc đã có cách giải quyết do Unity hoặc một thành viên cộng đồng đưa ra.
  • Xem báo cáo ANR trên Google Play và đảm bảo rằng Google chưa xác định lỗi. Google nhận biết được một số lỗi ANR và đang tích cực tìm cách khắc phục.

Thư viện hệ thống

Các thư viện hệ thống thường nằm ngoài tầm kiểm soát của nhà phát triển, nhưng không đại diện cho một tỷ lệ phần trăm đáng kể lỗi ANR. Ngoài việc liên hệ với nhà phát triển thư viện hoặc thêm nhật ký để thu hẹp vấn đề, lỗi ANR trong thư viện hệ thống còn rất khó giải quyết.

Lý do thoát

ApplicationExitInfo là một API Android để tìm hiểu nguyên nhân gây ra lỗi ANR. Nếu trò chơi của bạn đang sử dụng Unity 6 trở lên, bạn có thể gọi trực tiếp ApplicationExitInfo. Đối với các phiên bản Unity cũ, bạn cần triển khai trình bổ trợ của riêng mình để bật lệnh gọi ApplicationExitInfo từ Unity.

Crashlytics cũng sử dụng ApplicationExitInfo; tuy nhiên, cách triển khai của riêng bạn sẽ giúp bạn kiểm soát tốt hơn và cho phép bạn đưa vào thông tin phù hợp hơn.