Debugowanie błędów ANR

Rozwiązywanie problemów z ANR w grze w Unity to proces systematyczny:

Rysunek 1. Rozwiązywanie problemów z ANR w grach na platformie Unity.

Integrowanie usług raportowania

Usługi raportowania, takie jak Android Vitals, Firebase CrashlyticsBacktrace (certyfikowany partner Unity), zapewniają rejestrowanie i analizowanie błędów w grze na dużą skalę. Zintegruj pakiety SDK usług raportowania z grą na wczesnym etapie cyklu rozwoju. Przeanalizuj, która usługa raportowania najlepiej odpowiada potrzebom Twojej gry i Twojemu budżetowi.

Różne usługi raportowania mają różne sposoby rejestrowania błędów ANR. Użyj drugiej usługi raportowania, aby zwiększyć szansę na uzyskanie prawidłowych danych, które pomogą Ci podjąć decyzję o naprawie błędów ANR.

Integracja pakietów SDK do raportowania nie ma wpływu na wydajność gry ani rozmiar pliku APK.

Analizowanie symboli

Przeanalizuj raporty z usługi raportowania i sprawdź, czy ślady stosu są w formacie czytelnym dla człowieka. Więcej informacji znajdziesz w artykule Symbolizacja błędów i błędów ANR na Androidzie w przypadku gier na 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 nadal znajdują się w pamięci urządzenia, na którym została utworzona kompilacja, możesz sprawdzić identyfikator kompilacji symboli, a następnie 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 w zależności od backendu skryptowego (patrz Rozwiązanie):
    1. Użyj tego polecenia (w systemie Windows użyj Cygwin, aby uruchomić narzędzie readelf):
    2. Użycie polecenia grep jest opcjonalne i służy do filtrowania tekstu wyjściowego.
    3. Znajdź identyfikator kompilacji
readelf -n libil2cpp.so | grep 'Build ID'
Build ID: b42473fb7449e44e0182dd1f580c99bab0cd8a95

Sprawdzanie kodu gry

Jeśli ślad stosu wskazuje funkcję w bibliotece libil2cpp.so, oznacza to, że błąd wystąpił w kodzie C#, który jest konwertowany na C++. Biblioteka libil2cpp.so zawiera nie tylko kod gry, ale też wtyczki i pakiety.

Nazwa pliku C++ jest zgodna z nazwą zestawu zdefiniowaną w projekcie Unity. W przeciwnym razie nazwa pliku będzie miała domyślną nazwę Assembly-C#. Na przykład na rysunku 3 widać błąd w pliku Game.cpp (zaznaczonym na niebiesko), który jest nazwą zdefiniowaną w pliku definicji zestawu. Logger to nazwa klasy (wyróżniona na czerwono) w skrypcie C#, a następnie nazwa funkcji (wyróżniona na zielono). Finally to pełna nazwa wygenerowana przez konwerter IL2CPP (wyróżniona na pomarańczowo).

Rysunek 3. Stos wywołań projektu testowego z Backtrace.

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

  • Sprawdź, czy w projekcie C# nie ma podejrzanego kodu. Zazwyczaj nieobsłużone wyjątki w języku C# nie powodują błędu ANR ani awarii aplikacji. Mimo to upewnij się, że kod działa prawidłowo w różnych sytuacjach. Sprawdź, czy kod korzysta z modułu silnika innej firmy, i przeanalizuj, czy błąd nie został wprowadzony w ostatniej wersji. Sprawdź też, czy ostatnio nie została zaktualizowana platforma Unity lub czy błąd występuje tylko na określonych urządzeniach.
  • Wyeksportuj grę jako projekt Android Studio. Dzięki pełnemu dostępowi do przekonwertowanego kodu źródłowego C# gry możesz znaleźć funkcję, która powoduje błąd ANR. Kod C++ bardzo różni się od kodu C#, a konwersja kodu rzadko sprawia problemy. Jeśli coś znajdziesz, prześlij zgłoszenie do zespołu pomocy Unity.
  • Sprawdź kod źródłowy gry i upewnij się, że wszystkie reguły działania w funkcjach zwrotnych OnApplicationFocus()OnApplicationPause() są odpowiednio czyszczone.
    • Silnik Unity ma limit czasu, po którym wstrzymuje działanie. Nadmierne obciążenie tych wywołań zwrotnych może spowodować błąd ANR.
    • Dodaj do części kodu dzienniki lub ścieżki, aby ulepszyć analizę danych.
  • Użyj profilera Unity, aby sprawdzić wydajność gry. Profilowanie aplikacji może też pomóc w wykryciu wąskich gardeł, które mogą powodować błędy ANR.
  • Świetnym sposobem na rozpoznanie długich operacji wejścia-wyjścia w wątku głównym jest użycie trybu ścisłego.
  • Przeanalizuj historię Android Vitals lub innej usługi raportowania i sprawdź wersje gry, w których najczęściej występuje błąd. Sprawdzaj kod źródłowy w historii kontroli wersji i porównuj zmiany w kodzie między wersjami. Jeśli znajdziesz coś podejrzanego, wypróbuj każdą zmianę lub potencjalną poprawkę osobno.
  • Sprawdź historię raportowania błędów ANR w Google Play na urządzeniach i w wersjach Androida, w których występuje najwięcej błędów ANR. Jeśli urządzenia lub wersje są przestarzałe, możesz je bezpiecznie zignorować, o ile nie wpłynie to na rentowność gry. Dokładnie przeanalizuj dane, ponieważ określona grupa użytkowników nie będzie już mogła grać w Twoją grę. Więcej informacji znajdziesz w artykule Panel dystrybucji.
  • Sprawdź kod źródłowy gry, aby upewnić się, że nie wywołujesz żadnego kodu, który może powodować problemy. Na przykład funkcja finish może być destrukcyjna, jeśli nie jest używana prawidłowo. Więcej informacji o tworzeniu aplikacji na Androida znajdziesz w przewodnikach dla deweloperów aplikacji na Androida.
  • Po przejrzeniu danych i wyeksportowaniu kompilacji gry do Androida Studio masz do czynienia z kodem w językach C i C++, więc możesz w pełni korzystać z narzędzi wykraczających poza standardowe rozwiązania Unity, takich jak Android Memory Profiler, Android CPU Profilerperfetto.

Kod silnika Unity

Aby sprawdzić, czy błąd ANR występuje po stronie silnika Unity, poszukaj w śladach stosu symboli libUnity.so lub libMain.so. Jeśli je znajdziesz, wykonaj te czynności:

  • Najpierw przeszukaj kanały społeczności (fora Unity, dyskusje Unity, Stackoverflow).
  • Jeśli nic nie znajdziesz, zgłoś błąd, aby rozwiązać problem. Prześlij symboliczny ślad stosu, aby inżynierowie wyszukiwarki mogli lepiej zrozumieć i rozwiązać problem.
  • Sprawdź, czy najnowsza wersja Unity LTS zawiera ulepszenia związane z Twoimi problemami. Jeśli tak jest, uaktualnij grę, aby korzystać z tej wersji. (To rozwiązanie może być dostępne tylko dla niektórych deweloperów).
  • Jeśli Twój kod używa niestandardowego elementu Activity zamiast domyślnego, sprawdź kod Java, aby upewnić się, że działanie nie powoduje żadnych problemów.

Pakiet SDK firmy zewnętrznej

  • Sprawdź, czy wszystkie biblioteki innych firm są aktualne i czy w przypadku najnowszej wersji Androida nie zgłoszono awarii ani błędów ANR.
  • Odwiedź fora Unity, aby sprawdzić, czy błędy zostały już rozwiązane w nowszej wersji lub czy Unity albo członek społeczności zaproponował obejście problemu.
  • Sprawdź raport ANR w Google Play i upewnij się, że błąd nie został już zidentyfikowany przez Google. Google wie o niektórych błędach ANR i aktywnie pracuje nad ich rozwiązaniem.

Biblioteka systemowa

Biblioteki systemowe zwykle nie są kontrolowane przez programistę, ale nie stanowią znaczącego odsetka błędów ANR. Poza skontaktowaniem się z deweloperem biblioteki lub dodaniem logów w celu zawężenia problemu, błędy ANR w bibliotece systemowej są trudne do rozwiązania.

Przyczyny wyjścia

ApplicationExitInfo to interfejs API Androida, który pomaga zrozumieć przyczyny błędów ANR. Jeśli Twoja gra korzysta z Unity 6 lub nowszej wersji, możesz wywołać ApplicationExitInfo bezpośrednio. W przypadku starszych wersji Unity musisz wdrożyć własną wtyczkę, aby włączyć wywołania ApplicationExitInfo z Unity.

Crashlytics też korzysta z ApplicationExitInfo, ale Twoja implementacja daje Ci większą kontrolę i umożliwia uwzględnianie bardziej istotnych informacji.