Debugowanie błędów ANR

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

Rysunek 1. Rozwiązywanie problemów z brakiem odpowiedzi w grach w Unity

Integracja usług raportowania

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

Różne usługi raportowania mają różne sposoby rejestrowania ANR. Uwzględnij drugą usługę raportowania, aby zwiększyć szansę na uzyskanie prawidłowych danych, które pomogą Ci podjąć decyzję o usunięciu ANR.

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

Analizowanie symboli

Przeanalizuj raporty z usługi raportowania i sprawdź, czy ścieżki stosu są w czytelnym formacie. Więcej informacji znajdziesz w artykule Symbolicate Android: awarie i błędy ANR w grach 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 maszyny kompilującej, 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 na podstawie backendu do skryptowania (patrz Rozwiązanie).
    1. Użyj tego polecenia (w systemie Windows uruchom narzędzie readelf za pomocą Cygwin).
    2. Użycie grep jest opcjonalne, aby przefiltrować tekst wyjściowy.
    3. Znajdź identyfikator kompilacji.
readelf -n libil2cpp.so | grep 'Build ID'
Build ID: b42473fb7449e44e0182dd1f580c99bab0cd8a95

Sprawdzanie kodu gry

Jeśli ślad stosu zawiera funkcję z biblioteki libil2cpp.so, błąd wystąpił w kodzie C#, który został przekształcony w 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 ma domyślną nazwę Assembly-C#. Na przykład rysunek 3 pokazuje błąd w pliku Game.cpp (podświetlony na niebiesko), który jest nazwą zdefiniowaną w pliku definicji zestawu. Logger to nazwa klasy (podświetlona na czerwono) w skrypcie C#, po której następuje nazwa funkcji (podświetlona na zielono). Na koniec pełna nazwa wygenerowana przez konwerter IL2CPP (podświetlona na pomarańczowo).

Rysunek 3. Sprawdzanie stosu wywołań projektu w Backtrace.

Sprawdź kod gry:

  • Sprawdź, czy w projekcie C# nie ma podejrzanego kodu. Zwykle nieobsługiwane wyjątki w 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 używa modułu silnika innej firmy, i sprawdź, czy błąd został wprowadzony w ostatniej wersji. Sprawdź też, czy niedawno aktualizowano 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++ wygląda zupełnie inaczej niż kod C#, a konwersja kodu rzadko powoduje problemy. Jeśli coś znajdziesz, prześlij zgłoszenie do Unity.
  • Sprawdź kod źródłowy gry i upewnij się, że wszystkie reguły działania w funkcjach zwracających OnApplicationFocus()OnApplicationPause() są odpowiednio oczyszczone.
    • Silnik Unity ma limit czasu, po którego upływie zawiesza wykonywanie. Nadmierne obciążenie tych wywołań może spowodować błąd ANR.
    • Dodaj do części kodu logi lub ścieżki, aby ulepszyć analizę danych.
  • Aby sprawdzić wydajność gry, użyj profilowania Unity. Profilowanie aplikacji może też być świetnym sposobem na wykrycie wąskich gardeł, które mogą powodować błędy ANR.
  • Doskonałym sposobem na zidentyfikowanie długich operacji wejścia-wyjścia w wątku głównym jest użycie trybu rygorystycznego.
  • Przeanalizuj historię Android Vitals lub innej usługi raportowania i sprawdź wersje wersji gry, w których błąd występuje najczęściej. Sprawdź kod źródłowy w historii kontroli wersji i porównaj zmiany kodu między wersjami. Jeśli zauważysz coś podejrzanego, eksperymentalnie zastosuj każdą zmianę lub potencjalne rozwiązanie.
  • Sprawdź historię raportowania błędów ANR w Google Play na urządzeniach i w wersjach Androida, które generują najwięcej takich błędów. Jeśli urządzenia lub wersje są przestarzałe, możesz je bezpiecznie zignorować, jeśli nie wpłynie to na rentowność gry. Uważnie przeanalizuj dane, ponieważ dana grupa użytkowników może nie mieć już możliwości grania w Twoją grę. Więcej informacji znajdziesz w panelu dystrybucji.
  • Sprawdź kod źródłowy gry, aby upewnić się, że nie wywołujesz kodu, który może spowodować problem. Na przykład wywołanie funkcji finish może być destruktywne, jeśli nie jest używane prawidłowo. Aby dowiedzieć się więcej o programowaniu na Androida, zapoznaj się z przewodnikiem dla deweloperów aplikacji na Androida.
  • Po sprawdzeniu danych i wyeksportowaniu wersji gry do Android Studio będziesz mieć do czynienia z kodem C i C++, dzięki czemu będziesz mieć pełny dostęp do narzędzi wykraczających poza standardowe rozwiązania Unity, takich jak Android Memory Profiler, Android CPU Profilerperfetto.

Kod silnika Unity

Aby sprawdzić, czy ANR występuje po stronie silnika Unity, sprawdź, czy w śladach stosu występuje libUnity.so lub libMain.so. Jeśli je znajdziesz, wykonaj te czynności:

  • Najpierw wyszukaj na kanałach społeczności (fora Unity, dyskusje Unity, Stackoverflow).
  • Jeśli nie znajdziesz niczego, zgłoś błąd, aby rozwiązać problem. Prześlij symboliczną ścieżkę stosu, aby inżynierowie silnika mogli lepiej zrozumieć i rozwiązać problem.
  • Sprawdź, czy najnowsza wersja Unity LTS zawiera ulepszenia związane z Twoimi problemami. Jeśli tak, zaktualizuj grę, aby korzystać z 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 Activity zamiast domyślnego, sprawdź kod Java, aby upewnić się, że aktywność nie powoduje żadnych problemów.

Pakiet SDK firmy zewnętrznej

  • Sprawdź, czy wszystkie biblioteki innych firm są aktualne i nie zawierają raportów o awariach ani ANR w przypadku najnowszej wersji Androida.
  • Wejdź na fora Unity, aby sprawdzić, czy błędy zostały już rozwiązane w późniejszej wersji lub czy Unity lub członek społeczności podał sposób ich obejścia.
  • Zapoznaj się z raportami 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 dewelopera, ale nie stanowią znacznego odsetka ANR. Poza kontaktem z deweloperem biblioteky lub dodaniem logów w celu zawężenia zakresu problemu trudno jest rozwiązać problemy ANR biblioteki systemowej.

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 bezpośrednio wywołać funkcję ApplicationExitInfo. W przypadku starszych wersji Unity musisz zaimplementować własny wtyczek, aby umożliwić wywołania ApplicationExitInfo z Unity.

Crashlytics używa też ApplicationExitInfo, ale własna implementacja daje Ci większą kontrolę i umożliwia uwzględnienie bardziej odpowiednich informacji.