ANR-Fehler beheben

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

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

Berichtdienste einbinden

Berichtsdienste wie Android Vitals, Firebase Crashlytics und Backtrace (ein zertifizierter Unity-Partner) bieten Fehlerprotokollierung und ‑analyse für Ihr Spiel in großem Umfang. Integrieren Sie SDKs für Berichterstellungsdienste frühzeitig in Ihr Spiel. Analysieren Sie, welcher Berichterstellungsdienst am besten zu den Anforderungen und dem Budget Ihres Spiels passt.

Bei verschiedenen Berichterstellungsdiensten werden ANRs unterschiedlich erfasst. Fügen Sie einen zweiten Berichterstellungsdienst hinzu, um die Wahrscheinlichkeit zu erhöhen, dass Sie gültige Daten erhalten, die Ihnen bei der Entscheidung helfen, ANRs zu beheben.

Die Integration von Reporting-SDKs hat keine Auswirkungen auf die Spieleleistung oder die APK-Größe.

Symbole analysieren

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

Abbildung 2. Crashlytics zeigt die Build-ID und fehlende libil2cpp.so-Symbole an.

Symbol-Build-ID prüfen

Wenn im Berichtssystem die fehlende Build-ID angezeigt wird, die Build-Symbole aber weiterhin im Speicher des Build-Computers 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 den Symbolordner basierend auf Ihrem Scripting-Backend auf (siehe Lösung):
    1. Verwenden Sie den folgenden Befehl (unter Windows verwenden Sie Cygwin, um das readelf-Dienstprogramm auszuführen):
    2. Die Verwendung von „grep“ ist optional, um die Textausgabe zu filtern.
    3. Nach Build-ID suchen
readelf -n libil2cpp.so | grep 'Build ID'
Build ID: b42473fb7449e44e0182dd1f580c99bab0cd8a95

Spielcode ansehen

Wenn der Stacktrace eine Funktion in der libil2cpp.so-Bibliothek enthält, 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 Assembly-Namen. Andernfalls hat der Dateiname den Standardnamen „Assembly-C#“. Abbildung 3 zeigt beispielsweise den Fehler in der Datei Game.cpp (blau hervorgehoben), die in der Assembly Definition-Datei definiert ist. Logger ist der Klassenname (rot hervorgehoben) im C#-Script, gefolgt vom Funktionsnamen (grün hervorgehoben). „Finally“ ist der vollständige Name, der vom IL2CPP-Konverter generiert wurde (orange hervorgehoben).

Abbildung 3: Testen Sie den Aufrufstack des Projekts über Backtrace.

So prüfen Sie den Code Ihres Spiels:

  • Untersuchen Sie das C#-Projekt auf verdächtigen Code. In der Regel führen unbehandelte C#-Ausnahmen nicht zu einem ANR-Fehler oder einem Absturz der Anwendung. Achten Sie trotzdem darauf, dass der Code in verschiedenen Situationen richtig ausgeführt wird. Prüfen Sie, ob im Code ein Engine-Modul eines Drittanbieters verwendet wird, und analysieren Sie, ob der Fehler durch eine aktuelle Version eingeführt wurde. Prüfe außerdem, ob du Unity vor Kurzem aktualisiert hast oder ob der Fehler nur auf bestimmten Geräten auftritt.
  • Exportieren Sie das Spiel als Android Studio-Projekt. Da Sie vollständigen Zugriff auf den konvertierten C#-Quellcode Ihres Spiels haben, können Sie die Funktion finden, die den ANR verursacht. Der C++-Code sieht ganz anders aus als Ihr C#-Code und die Codekonvertierung ist selten problematisch. Wenn Sie etwas finden, reichen Sie ein Support-Ticket bei Unity ein.
  • Prüfen Sie den Quellcode des Spiels und sorgen Sie dafür, dass alle Logik, die in den Callbacks 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 Protokolle oder Breadcrumbs in Teile des Codes ein, um die Datenanalyse zu verbessern.
  • Verwenden Sie den Unity Profiler, um die Leistung des Spiels zu untersuchen. Durch das Profiling Ihrer App können Sie auch Engpässe ermitteln, die möglicherweise die ANR verursachen.
  • Eine gute Möglichkeit, lange E/A-Vorgänge im Hauptthread zu erkennen, ist die Verwendung des Strict Mode.
  • Analysieren Sie den Verlauf von Android Vitals oder eines anderen Berichterstellungsdienstes und prüfen Sie die Release-Versionen des Spiels, bei denen der Fehler am häufigsten auftritt. Sehen Sie sich Ihren Quellcode im Versionskontrollverlauf an und vergleichen Sie Codeänderungen zwischen Releases. Wenn Sie etwas Verdächtiges finden, testen Sie jede Änderung oder potenzielle Korrektur einzeln.
  • Sehen Sie sich den Google Play-ANR-Berichtsverlauf für die Geräte und Android-Versionen an, bei denen die meisten ANR-Fehler auftreten. Wenn die Geräte oder Versionen veraltet sind, können Sie sie wahrscheinlich ignorieren, sofern dies die Rentabilität des Spiels nicht beeinträchtigt. Sehen Sie sich die Daten genau an, da eine bestimmte Nutzergruppe Ihr Spiel nicht mehr spielen kann. Weitere Informationen finden Sie unter Distributions-Dashboard.
  • Prüfen Sie den Quellcode des Spiels, um sicherzustellen, dass Sie keinen Code aufrufen, der Probleme verursachen könnte. Die Funktion finish kann beispielsweise destruktiv sein, wenn sie nicht richtig verwendet wird. Weitere Informationen zur Android-Entwicklung finden Sie in den Android-Entwicklerleitfäden.
  • Nachdem Sie die Daten geprüft und den Game-Build in Android Studio exportiert haben, können Sie C- und C++-Code bearbeiten und so Tools nutzen, die über die Standardlösungen von Unity hinausgehen, z. B. den Android Memory Profiler, den Android CPU Profiler und Perfetto.

Unity-Engine-Code

Wenn Sie wissen möchten, ob ein ANR auf der Unity-Engine-Seite auftritt, suchen Sie in den Stacktraces nach libUnity.so oder libMain.so. Wenn Sie sie finden, gehen Sie so vor:

  • Suchen Sie zuerst in den Community-Kanälen (Unity-Foren, Unity-Diskussionen, Stack Overflow).
  • Wenn Sie nichts finden, melden Sie einen Fehler, um das Problem zu beheben. Stellen Sie einen symbolisierten Stacktrace bereit, damit die Entwickler der Engine den Fehler besser nachvollziehen und beheben können.
  • Prüfen Sie, ob die aktuelle Unity LTS Verbesserungen enthält, die sich auf Ihre Probleme beziehen. Aktualisieren Sie Ihr Spiel in diesem Fall auf diese Version. (Diese Lösung ist möglicherweise nur für einige Entwickler möglich.)
  • Wenn in Ihrem Code ein benutzerdefiniertes Activity anstelle des Standard-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 ob es für die aktuelle Android-Version Berichte zu Abstürzen oder ANR-Fehlern gibt.
  • Sehen Sie in den Unity-Foren nach, ob Fehler bereits in einer späteren Version behoben wurden oder ob Unity oder ein Community-Mitglied eine Behelfslösung bereitgestellt hat.
  • Sehen Sie sich den ANR-Bericht von Google Play an und prüfen Sie, ob der Fehler bereits von Google erkannt wurde. Google ist sich einiger ANR-Fehler bewusst und arbeitet aktiv an einer Lösung.

Systembibliothek

Systembibliotheken sind in der Regel nicht unter der Kontrolle des Entwicklers, machen aber keinen erheblichen Prozentsatz der ANRs aus. Neben der Kontaktaufnahme mit dem Bibliotheksentwickler oder dem Hinzufügen von Logs zur Eingrenzung des Problems sind ANRs in Systembibliotheken schwer zu beheben.

Gründe für das Beenden

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

Crashlytics verwendet ebenfalls ApplicationExitInfo. Ihre eigene Implementierung bietet Ihnen jedoch mehr Kontrolle und ermöglicht es Ihnen, relevantere Informationen einzubeziehen.