Debugowanie błędów ANR

Rozwiązywanie błędów ANR w grze Unity to systematyczny proces:

Rysunek 1. Jak rozwiązywać problemy z błędami ANR w grach na Unity.

Integrowanie usług raportowania

Usługi raportowania takie jak Android Vitals, Firebase Crashlytics i Backtrace (certyfikowany partner Unity) umożliwiają rejestrowanie i analizę błędów związanych z grami na dużą skalę. Zintegruj pakiety SDK usług raportowania z grą na wczesnym etapie programowania. Przeanalizuj, która usługa raportowania najlepiej pasuje do Twoich potrzeb i budżetu.

Różne usługi raportowania mogą rejestrować błędy ANR w różny sposób. Uwzględnienie drugiej usługi raportowania, aby zwiększyć szanse na uzyskanie prawidłowych danych na potrzeby podjęcia decyzji o naprawianiu błędów ANR.

Zintegrowanie pakietów SDK do raportowania nie wpływa na wydajność gry ani rozmiar pliku APK.

Przeanalizuj symbole

Przeanalizuj raporty z usługi raportowania i sprawdź, czy zrzuty stosu są w formacie zrozumiałym dla człowieka. Więcej informacji znajdziesz w artykule o awariach Androida i błędach ANR na platformie Unity.

Rysunek 2. Crashlytics wyświetla identyfikator kompilacji i brakujące symbole (libil2cpp.so).

Jak sprawdzić identyfikator kompilacji symbolu

Jeśli system raportowania pokazuje brakujący identyfikator kompilacji, ale symbole kompilacji są nadal zapisane w pamięci maszyny do tworzenia, możesz sprawdzić identyfikator kompilacji symboli i przesłać je do usługi raportowania. W przeciwnym razie do przesłania plików symboli wymagana jest nowa kompilacja.

W systemie Windows lub macOS:

  1. Przejdź do folderu symboli na podstawie swojego backendu obsługi skryptów (patrz Rozwiązanie:)
    1. Użyj tego polecenia (w systemie Windows użyj Cygwin, aby uruchomić narzędzie readelf):
    2. Użycie Grep jest opcjonalne do filtrowania danych wyjściowych tekstowych
    3. Znajdź identyfikator kompilacji
readelf -n libil2cpp.so | grep 'Build ID'
Build ID: b42473fb7449e44e0182dd1f580c99bab0cd8a95

Sprawdzanie kodu gry

Gdy zrzut stosu pokazuje funkcję w bibliotece libil2cpp.so, błąd wystąpił w kodzie C#, który jest konwertowany do formatu C++. Biblioteka libil2cpp.so zawiera nie tylko kod gry, ale również wtyczki i pakiety.

Nazwa pliku w C++ jest taka sama jak nazwa zestawu zdefiniowana w projekcie Unity. W przeciwnym razie nazwa pliku ma domyślną nazwę Assembly-C#. Na przykład na ilustracji 3 widać błąd w pliku Game.cpp (wyróżniony na niebiesko), który jest nazwą zdefiniowaną w pliku definicji zestawu. Logger to nazwa klasy (wyróżniona na czerwono) w skrypcie C#, po której następuje nazwa funkcji (wyróżniona na zielono). Na koniec znajduje się pełna nazwa, która została wygenerowana przez konwerter IL2CPP (wyróżniona na pomarańczowo).

Rysunek 3. Przetestuj stos wywołań projektu z backtrace.

Sprawdź kod gry, wykonując te czynności:

  • Poszukaj podejrzanego kodu w projekcie C#. Zwykle nieobsługiwane wyjątki w języku C# nie powodują błędów ANR ani awarii aplikacji. Mimo to upewnij się, że kod działa prawidłowo w różnych sytuacjach. Sprawdź, czy w kodzie używany jest moduł wyszukiwarki innej firmy, i przeanalizuj, czy błąd nie pojawił się w ostatniej wersji. Sprawdź też, czy błąd był niedawno aktualizowany, czy problem pojawia się tylko na konkretnych urządzeniach.
  • Wyeksportuj grę jako projekt Android Studio. Mając pełny dostęp do przekonwertowanego kodu źródłowego gry w języku C#, możesz znaleźć funkcję, która powoduje błąd ANR. Kod C++ bardzo różni się od kodu C#, a z konwersją rzadko występują problemy. Jeśli znajdziesz rozwiązanie, prześlij zgłoszenie do Unity.
  • Sprawdź kod źródłowy gry i upewnij się, że wszystkie funkcje logiczne uruchomione w wywołaniach zwrotnych OnApplicationFocus() i OnApplicationPause() zostały odpowiednio wyczyszczone.
    • Mechanizm Unity ma limit czasu oczekiwania na wstrzymanie wykonania; nadmierne obciążenie tymi wywołaniami zwrotnymi może powodować błąd ANR.
    • Dodaj dzienniki lub menu nawigacyjne do części kodu, aby usprawnić analizę danych.
  • Aby sprawdzić wydajność gry, użyj Unity Profiler. Profilowanie aplikacji może też pomóc w identyfikacji wątków, które mogą być przyczyną błędu ANR.
  • Świetnym sposobem na identyfikowanie długich operacji wejścia-wyjścia w wątku głównym jest użycie trybu ścisłego.
  • Przeanalizuj Android Vitals lub historię usługi raportowania i sprawdź, w których wersjach gry występuje najwięcej błędów. Sprawdź kod źródłowy w historii kontroli wersji i porównaj zmiany kodu między wersjami. Jeśli zauważysz coś podejrzanego, poeksperymentuj z każdą zmianą lub poprawką osobno.
  • Sprawdź historię zgłoszeń błędów ANR w Google Play w przypadku urządzeń i wersji Androida, w których występuje najwięcej błędów ANR. Jeśli urządzenia lub wersje są nieaktualne, możesz je bezpiecznie zignorować, jeśli nie wpłynie to na rentowność gry. Dane należy dokładnie badać, ponieważ konkretna grupa użytkowników nie będzie już mogła grać w Twoją grę. Więcej informacji znajdziesz w artykule o panelu dystrybucji.
  • Sprawdź kod źródłowy gry, aby mieć pewność, że nie wywołujesz żadnego kodu, który mógłby powodować problem, np. nieprawidłowy kod finish może być szkodliwy. Więcej o programowaniu aplikacji na Androida dowiesz się z przewodników dla programistów aplikacji na Androida.
  • Po zapoznaniu się z danymi i wyeksportowaniu kompilacji gry do Android Studio masz do czynienia z kodem w języku C i C++, dzięki czemu możesz w pełni korzystać z narzędzi innych niż standardowe rozwiązania Unity, takich jak Android Memory Profiler, Android CPU Profiler i perfetto.

Kod silnika Unity

Aby dowiedzieć się, czy błąd ANR występuje po stronie silnika Unity, sprawdź w zrzucie stosu libUnity.so lub libMain.so. Jeśli je znajdziesz, wykonaj te czynności:

  • Najpierw przeszukaj kanały społeczności (Fora Unity, Unityforums, Stackoverflow).
  • Jeśli nie znajdziesz niczego, zgłoś błąd, aby rozwiązać problem. Udostępnij zrzut stosu z symbolami, aby inżynierowie wyszukiwarki mogli lepiej zrozumieć i rozwiązać problem.
  • Sprawdź, czy najnowsza wersja Unity LTS wprowadziła ulepszenia związane z problemami. Jeśli tak, uaktualnij grę do tej wersji. (To rozwiązanie może być możliwe tylko w przypadku niektórych deweloperów).
  • Jeśli Twój kod używa niestandardowego elementu Activity zamiast domyślnego, sprawdź kod w języku Java, aby upewnić się, że aktywność nie powoduje żadnych problemów.

Pakiet SDK firmy zewnętrznej

  • Sprawdź, czy wszystkie biblioteki zewnętrzne są aktualne i nie występują w nich zgłoszenia o awariach lub błędach ANR w najnowszej wersji Androida.
  • Wejdź na fora Unity, by sprawdzić, czy jakieś błędy nie zostały już naprawione w nowszej wersji lub czy obejście to zostało wprowadzone przez Unity lub członka społeczności.
  • Zapoznaj się z raportem o błędach ANR w Google Play i upewnij się, że błąd nie został już zidentyfikowany przez Google. Google wie o niektórych błędach i pracuje nad ich rozwiązaniem.

Biblioteka systemowa

Biblioteki systemowe zazwyczaj pozostają poza kontrolą dewelopera, ale nie stanowią one znacznego procentu błędów ANR. Poza skontaktowaniem się z deweloperem biblioteki lub dodaniem logów w celu zdefiniowania problemu błędy ANR w bibliotece systemowej są trudne do rozwiązania.

Przyczyny rezygnacji

ApplicationExitInfo to interfejs API Androida służący do analizowania przyczyn błędów ANR. Jeśli Twoja gra korzysta z wersji Unity 6 lub nowszej, możesz zadzwonić bezpośrednio pod numer ApplicationExitInfo. W przypadku starszych wersji Unity musisz wdrożyć własną wtyczkę, by włączyć wywołania ApplicationExitInfo z Unity.

Crashlytics również używa ApplicationExitInfo. Własna implementacja zapewnia jednak dokładniejszą kontrolę i umożliwia dołączenie bardziej istotnych informacji.