ANR-Fehler beheben

Das Beheben von ANRs in Ihrem Unity-Spiel ist ein systematischer Prozess:

Abbildung 1: Schritte zur Behebung von ANRs in Unity-Spielen.

Berichterstellungsdienste einbinden

Berichtsdienste wie Android Vitals, Firebase Crashlytics und Backtrace (ein zertifizierter Unity-Partner) bieten Fehler-Logging und -Analysen für Ihr Spiel in großem Maßstab. Integrieren Sie SDKs für Berichtsdienste schon früh im Entwicklungszyklus in Ihr Spiel. Analysieren Sie, welcher Berichterstellungsdienst am besten zu Ihren Spielanforderungen und Ihrem Budget passt.

Unterschiedliche Meldedienste erfassen ANRs auf unterschiedliche Weise. Fügen Sie einen zweiten Berichtsdienst hinzu, um die Wahrscheinlichkeit zu erhöhen, dass gültige Daten abgerufen werden und Sie sich bei der Behebung von ANR-Fehlern besser entscheiden können.

Die Einbindung von SDKs für die Berichterstellung hat keine Auswirkungen auf die Leistung des Spiels oder die APK-Größe.

Symbole analysieren

Analysieren Sie die Berichte Ihres Berichtsdienstes und prüfen Sie, ob die Stacktraces in einem visuell lesbaren Format vorliegen. Weitere Informationen finden Sie unter Android-Abstürze und ANR für Unity-Spiele symbolisieren.

Abbildung 2: In Crashlytics werden die Build-ID und fehlende libil2cpp.so-Symbole angezeigt.

Symbol-Build-ID prüfen

Wenn das Berichtssystem die fehlende Build-ID anzeigt, die Buildsymbole aber noch im Speicher der Buildmaschine vorhanden sind, können Sie die Build-ID der Symbole prüfen und sie dann in den Berichtsdienst hochladen. Andernfalls ist ein neuer Build erforderlich, um die Symboldateien hochzuladen.

Unter Windows oder macOS:

  1. Rufen Sie basierend auf Ihrem Scripting-Back-End den Symbolordner auf (siehe Lösung:)
    1. Verwenden Sie den folgenden Befehl. Unter Windows müssen Sie Cygwin verwenden, um das readelf-Dienstprogramm auszuführen.
    2. Die Verwendung von Grep zum Filtern der Textausgabe ist optional.
    3. Build-ID suchen
readelf -n libil2cpp.so | grep 'Build ID'
Build ID: b42473fb7449e44e0182dd1f580c99bab0cd8a95

Spielcode prüfen

Wenn der Stacktrace eine Funktion in der libil2cpp.so-Bibliothek anzeigt, ist der Fehler im C#-Code aufgetreten, der in C++ konvertiert wird. Die libil2cpp.so-Bibliothek enthält nicht nur Ihren Spielcode, sondern auch Plug-ins und Pakete.

Der C++-Dateiname entspricht dem im Unity-Projekt definierten Assembliesnamen. Andernfalls hat der Dateiname den Standardnamen der Assembly-C#-Datei. Abbildung 3 zeigt beispielsweise den Fehler in der Datei Game.cpp (blau hervorgehoben), der in der Assembly-Definitiondatei definiert ist. Logger ist der Klassenname (rot hervorgehoben) im C#-Script, gefolgt vom Funktionsnamen (grün hervorgehoben). Schließlich wird der vollständige Name angezeigt, den der IL2CPP-Konverter generiert hat (orange hervorgehoben).

Abbildung 3: Aufrufstack des Projekts über Backtrace testen

So prüfen Sie Ihren Game-Code:

  • Prüfen Sie das C#-Projekt auf verdächtige Codeelemente. In der Regel verursachen unbehandelte C#-Ausnahmen keinen ANR-Fehler oder keinen Anwendungsabsturz. Achten Sie aber darauf, dass der Code in verschiedenen Situationen ordnungsgemäß ausgeführt wird. Prüfen Sie, ob im Code ein Engine-Modul eines Drittanbieters verwendet wird, und analysieren Sie, ob der Fehler durch eine neuere Version verursacht wurde. Prüfen Sie außerdem, ob Sie Unity vor Kurzem aktualisiert haben oder ob der Fehler nur auf bestimmten Geräten auftritt.
  • Exportieren Sie das Spiel als Android Studio-Projekt. Wenn Sie uneingeschränkten Zugriff auf den konvertierten C#-Quellcode haben, können Sie die Funktion finden, die den ANR-Fehler verursacht. Der C++-Code unterscheidet sich stark von Ihrem C#-Code und bei der Codekonvertierung treten nur selten Probleme auf. Wenn Sie etwas finden, reichen Sie ein Support-Ticket bei Unity ein.
  • Prüfen Sie den Quellcode des Spiels und achten Sie darauf, dass alle Logik, die in den Rückrufen OnApplicationFocus() und OnApplicationPause() ausgeführt wird, ordnungsgemäß bereinigt wird.
    • Die Unity-Engine hat ein Zeitlimit, um die Ausführung zu pausieren. Eine übermäßige Arbeitslast bei diesen Rückrufen kann zu einem ANR führen.
    • Fügen Sie Teilen des Codes Protokolle oder Breadcrumbs hinzu, um Ihre Datenanalyse zu verbessern.
  • Verwenden Sie den Unity-Profiler, um die Leistung des Spiels zu analysieren. Außerdem können Sie mithilfe des App-Profils Engpässe ermitteln, die möglicherweise die Ursache für die ANR sind.
  • Eine gute Möglichkeit, lange E/A-Vorgänge im Hauptthread zu identifizieren, ist der strengen Modus.
  • Analysieren Sie den Verlauf von Android Vitals oder einem anderen Berichtsdienst und prüfen Sie die Releaseversionen des Spiels, bei dem der Fehler am häufigsten auftritt. Sehen Sie sich den Quellcode in Ihrem Versionskontrollverlauf an und vergleichen Sie die Codeänderungen zwischen den Releases. Wenn Sie etwas Verdächtiges finden, testen Sie jede Änderung oder potenzielle Lösung einzeln.
  • Prüfen Sie den Google Play-ANR-Berichtsverlauf für die Geräte und Android-Versionen, für die die meisten ANRs empfangen werden. Wenn die Geräte oder Versionen veraltet sind, können Sie sie in der Regel ignorieren, sofern dies die Rentabilität des Spiels nicht beeinträchtigt. Prüfen Sie die Daten sorgfältig, da eine bestimmte Gruppe von Nutzern Ihr Spiel nicht mehr spielen kann. Weitere Informationen finden Sie im Dashboard „Distribution“.
  • Prüfen Sie den Quellcode des Spiels, um sicherzustellen, dass Sie keinen Code aufrufen, der ein Problem verursachen könnte. finish kann beispielsweise schädlich sein, wenn er nicht richtig verwendet wird. Weitere Informationen zur Android-Entwicklung findest du in den Android-Entwicklerleitfäden.
  • Nachdem Sie die Daten geprüft und den Game-Build nach Android Studio exportiert haben, arbeiten Sie mit C- und C++-Code. Sie können also Tools wie den Android Memory Profiler, den Android CPU Profiler und perfetto nutzen, die über die Standardlösungen von Unity hinausgehen.

Unity-Engine-Code

Wenn Sie wissen möchten, ob ein ANR auf der Unity-Engine-Seite auftritt, suchen Sie in den Stack-Traces nach libUnity.so oder libMain.so. Führen Sie in diesem Fall die folgenden Schritte aus:

  • Suchen Sie zuerst in den Community-Kanälen (Unity-Foren, Unity-Diskussionen, Stackoverflow).
  • Wenn Sie nichts finden, melden Sie den Fehler, um das Problem zu beheben. Stellen Sie einen symbolischen Stack-Trace bereit, damit die Entwickler der Engine den Fehler besser verstehen und beheben können.
  • Prüfen Sie, ob die neuesten Unity-LTS-Versionen Verbesserungen in Bezug auf Ihre Probleme enthalten. Aktualisieren Sie Ihr Spiel in diesem Fall, um diese Version zu verwenden. Diese Lösung ist möglicherweise nur für einige Entwickler möglich.
  • Wenn in Ihrem Code anstelle des Standardwerts eine benutzerdefinierte Activity verwendet wird, prüfen Sie den Java-Code, um sicherzustellen, dass die Aktivität keine Probleme verursacht.

Drittanbieter-SDK

  • Prüfen Sie, ob alle Drittanbieterbibliotheken auf dem neuesten Stand sind und keine Abstürze oder ANRs für die neueste Android-Version gemeldet wurden.
  • Rufen Sie die Unity-Foren auf, um zu sehen, ob Fehler bereits in einer neueren Version behoben wurden oder ob Unity oder ein Communitymitglied eine Behelfslösung bereitgestellt hat.
  • Prüfen Sie den Google Play-ANR-Bericht und achten Sie darauf, dass der Fehler nicht bereits von Google erkannt wurde. Google ist sich einiger ANRs bewusst und arbeitet aktiv an deren Behebung.

Systembibliothek

Systembibliotheken liegen in der Regel nicht in der Kontrolle des Entwicklers, machen aber keinen signifikanten Prozentsatz der ANRs aus. Außer dem Kontakt mit dem Bibliotheksentwickler oder dem Hinzufügen von Protokollen zur Eingrenzung des Problems sind ANRs von Systembibliotheken nur schwer zu beheben.

Gründe für den Ausstieg

ApplicationExitInfo ist eine Android-API, mit der Sie die Ursachen von ANRs ermitteln können. Wenn in Ihrem Spiel Unity 6 oder höher verwendet wird, können Sie ApplicationExitInfo direkt aufrufen. Bei älteren Unity-Versionen müssen Sie ein eigenes Plug-in implementieren, um ApplicationExitInfo-Aufrufe von Unity zu ermöglichen.

Crashlytics verwendet auch ApplicationExitInfo. Mit Ihrer eigenen Implementierung haben Sie jedoch eine genauere Kontrolle und können relevantere Informationen angeben.