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 grze na dużą skalę. Zintegruj pakiety SDK usług raportowania ze swoją grą na wczesnym etapie cyklu rozwoju. Przeanalizuj, która usługa raportowania najlepiej pasuje do Twoich potrzeb i budżetu związanego z grami.

Różne usługi raportowania rejestrują ANR na różne sposoby. Uwzględnij drugą usługę raportowania, aby zwiększyć szansę na uzyskanie prawidłowych danych, które pomogą Ci w rozwiązaniu problemu z 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 dla człowieka 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 wyświetla brakujący identyfikator kompilacji, ale symbole kompilacji nadal istnieją w pamięci maszyny, możesz sprawdzić identyfikatory 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 obsługi skryptów (patrz Rozdzielczość:)
    1. Użyj tego polecenia (w systemie Windows uruchom narzędzie readelf za pomocą Cygwin).
    2. Użycie Grep jest opcjonalne do filtrowania danych wyjściowych.
    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. Przetestuj stos wywołań projektu z 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 korzysta z modułu innej firmy, i przeanalizuj, czy błąd spowodował w jednej z ostatnich 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 w C++ znacznie różni się od kodu w C#, a z konwersją kodu rzadko występują problemy. Jeśli coś znajdziesz, prześlij zgłoszenie do Unity.
  • Sprawdź kod źródłowy gry i upewnij się, że wszystkie funkcje logiczne uruchomione w wywołaniach OnApplicationFocus() i OnApplicationPause() zostały odpowiednio wyczyszczone.
    • Mechanizm Unity ma limit czasu na wstrzymanie wykonywania. Nadmierne obciążenie tymi wywołaniami zwrotnymi może spowodować błąd ANR.
    • Dodaj logi lub menu nawigacyjne do części kodu, aby ulepszyć analizę danych.
  • Aby sprawdzić wydajność gry, użyj Profilera Unity. Profilowanie aplikacji może też być świetnym sposobem na wykrycie wąskich gardeł, które mogą powodować błędy ANR.
  • Świetnym sposobem na identyfikowanie długich operacji wejścia-wyjścia w wątku głównym jest użycie trybu ścisłego.
  • Przeanalizuj dane Android Vitals lub historię innych usług raportowania i sprawdź wersje gier, w których ten 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ę raportów o błędach ANR w Google Play dotyczących urządzeń i wersji Androida, które otrzymują najwięcej błędów ANR. 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 już nie mieć 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 zostanie użyte niewłaściwie. 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 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 dowiedzieć się, czy błąd ANR występuje po stronie silnika Unity, w zrzutach stosu sprawdź pole libUnity.so lub libMain.so. Jeśli je znajdziesz, wykonaj te czynności:

  • Najpierw przeszukaj kanały społeczności (Fora Unity, Unity Forums, Stackoverflow).
  • Jeśli nie znajdziesz niczego, zgłoś błąd, aby rozwiązać problem. Prześlij symboliczny ślad stosu, aby inżynierowie silnika mogli lepiej zrozumieć i rozwiązać problem.
  • Sprawdź, czy w najnowszej wersji Unity LTS wprowadzono ulepszenia związane z Twoimi problemami. Jeśli tak, zaktualizuj grę, aby korzystać z tej wersji. (Takie rozwiązanie może być możliwe tylko w przypadku niektórych programistów).
  • Jeśli Twój kod używa niestandardowego Activity zamiast domyślnego, sprawdź kod Java, aby upewnić się, że ta 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 jakieś błędy nie zostały już naprawione w nowszej wersji albo czy Unity lub członek społeczności udostępnił Ci obejście.
  • Przejrzyj raport ANR w Google Play i upewnij się, że błąd nie został już zidentyfikowany przez Google. Wiemy o niektórych błędach ANR i pracujemy nad ich usunięciem.

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.