ANR-Fehler diagnostizieren und beheben

Wenn der UI-Thread einer Android-App zu lange blockiert ist, sendet das System die Meldung „App reagiert nicht“ (ANR-Fehler). Auf dieser Seite werden die verschiedenen Arten von ANR-Fehlern, wie sie zu diagnostizieren und zu beheben sind. Alle Die standardmäßigen Zeitüberschreitungszeiträume gelten für AOSP- und Pixel-Geräte. diese Zeiten kann je nach OEM variieren.

Bei der Ermittlung der Ursache von ANR-Fehlern ist es hilfreich, zwischen System- und App-Problemen unterscheiden.

Wenn sich das System in einem schlechten Zustand befindet, können die folgenden Probleme ANR-Fehler verursachen:

  • Vorübergehende Probleme im Systemserver führen in der Regel zu schnellen Binder-Aufrufen. langsam ist.
  • Probleme mit dem Systemserver und eine hohe Geräteauslastung führen dazu, dass App-Threads nicht geplant.

So können Sie zwischen System- und App-Problemen unterscheiden: Perfetto-Traces verwendet werden:

  • Thread-Status prüfen, um festzustellen, ob der Hauptthread der App geplant ist in Perfetto, um zu sehen, ob sie läuft.
  • Suchen Sie in den system_server-Threads nach Problemen wie Sperrenkonflikten.
  • Sehen Sie sich bei langsamen Binder-Aufrufen den Antwort-Thread an, falls vorhanden. langsam ist.

Zeitlimit für Eingabeweiterleitung

Eingabe-ANRs treten auf, wenn der Hauptthread der App nicht auf eine Eingabe reagiert wie Wischen oder Tastendruck in der Zeit. Da die App im Vordergrund ausgeführt wird, Wenn Zeitüberschreitungen beim Versand von Eingaben auftreten, sind diese für den Nutzer fast immer sichtbar. und es ist sehr wichtig, das Risiko zu minimieren.

Standardmäßiges Zeitlimit: 5 Sekunden.

Eingabe-ANRs werden in der Regel durch Probleme im Hauptthread verursacht. Wenn die wichtigsten Thread blockiert wurde, weil auf den Erhalt einer Sperre gewartet wurde, kann der Halter-Thread auch beteiligt sind.

Beachten Sie die folgenden Best Practices, um ANRs bei der Eingabeweiterleitung zu vermeiden:

  • Führen Sie keine blockierenden oder lang andauernden Vorgänge für den Hauptthread aus. Erwägen Sie mit StrictMode, um versehentliche Aktivitäten im Hauptthread.
  • Minimieren Sie Sperrkonflikte zwischen dem Hauptthread und anderen Threads.
  • Minimieren Sie die Arbeit im Hauptthread, die nicht auf der Benutzeroberfläche erfolgen soll, z. B. bei der Verarbeitung von Broadcasts oder ausgeführte Dienste.

Häufige Ursachen

Im Folgenden finden Sie einige häufige Ursachen und Lösungsvorschläge für ANR-Fehler bei der Eingabe.

Ursache Was passiert? Korrekturvorschläge
Langsamer Binder-Aufruf Der Hauptthread führt einen langen synchronen Binder-Aufruf aus. Verschieben Sie den Anruf aus dem Hauptthread oder versuchen Sie, ihn zu optimieren, die API gehören.
Viele aufeinanderfolgende Binder-Aufrufe Der Hauptthread führt viele aufeinanderfolgende synchrone Binder-Aufrufe aus. Führen Sie Binder-Aufrufe nicht in einer engen Schleife aus.
E/A blockieren Der Hauptthread führt zu blockierenden E/A-Aufrufen, z. B. Datenbank oder Netzwerk Zugriff haben. Entfernen Sie alle blockierenden Anzeigenaufträge aus dem Hauptthread.
Sperrkonflikt Der Hauptthread ist blockiert und wartet auf den Erhalt einer Sperre. Reduzieren Sie Sperrkonflikte zwischen dem Hauptthread und dem anderen Thread. Optimieren Sie langsamen Code im anderen Thread.
Teurer Rahmen Zu viel Rendering in einem einzelnen Frame, was zu einer erheblichen Verzögerung führt. Erledigen Sie weniger Arbeit beim Verzerren des Frames. Verwenden Sie keine n2-Algorithmen. Verwenden Sie effiziente Komponenten für Dinge wie Scrollen oder Paging – zum Beispiel die Jetpack (Raketenrucksack) Paging Library.
Durch andere Komponente blockiert Eine andere Komponente, z. B. ein Übertragungsempfänger, wird ausgeführt und und blockieren den Hauptthread. Verschieben Sie Aufgaben, die nicht auf der Benutzeroberfläche basieren, so weit wie möglich aus dem Hauptthread. Broadcast ausführen Empfänger in einem anderen Thread.
GPU hängt Ein Problem mit der GPU ist ein System- oder Hardwareproblem, zu blockieren, sodass eine Eingabe einen ANR-Fehler auslöst. In der Regel gibt es leider keine Probleme aufseiten der App. Wenn zur Fehlerbehebung das Hardware-Team kontaktieren.

Fehlerbehebung

Sehen Sie sich zur Fehlerbehebung die Signatur des ANR-Clusters in Google Play an. Console oder Firebase Crashlytics Der Cluster enthält in der Regel die oberste Frames verursacht, die im Verdacht stehen, den ANR-Fehler zu verursachen.

Das folgende Flussdiagramm zeigt, wie Sie die Ursache einer Zeitüberschreitung bei der Eingabe ermitteln. einen ANR-Fehler aus.

<ph type="x-smartling-placeholder">
</ph> Abbildung 1: Anleitung zum Debuggen eines Eingabe-ANR-Fehlers.

Play Vitals kann einige dieser häufigen ANR-Ursachen erkennen und bei der Fehlerbehebung helfen. Für Wenn z. B. ein ANR-Fehler aufgrund eines Sperrkonflikts erkannt wird, können Sie das Problem und die empfohlene Problembehebung im Bereich ANR-Statistiken zusammenfassen.

<ph type="x-smartling-placeholder">
</ph> Abbildung 2: Play Vitals-ANR-Erkennung.

Kein fokussiertes Fenster

Ereignisse wie Berührungen werden über den Treffer direkt an das relevante Fenster gesendet. Tests erfordern Ereignisse wie Schlüssel ein Ziel. Dieses Ziel wird als fokussierten Fenster öffnen. Es gibt nur ein fokussiertes Fenster pro Anzeige, das normalerweise das Fenster, mit dem der Nutzer derzeit interagiert. Wenn ein fokussiertes Fenster nicht gefunden werden kann, löst die Eingabe einen ANR-Fehler (kein Fokusfenster) aus. Ein ANR-Fehler ohne Fokusfenster ist eine Art von Eingabe- ANR-Fehler.

Standardmäßiges Zeitlimit: 5 Sekunden.

Häufige Ursachen

ANR-Fehler mit fokussiertem Fenster werden normalerweise durch eines der folgenden Probleme verursacht:

  • Die App macht zu viel Arbeit und ist zu langsam, um den ersten Frame zu zeichnen.
  • Das Hauptfenster ist nicht fokussierbar. Wenn ein Fenster mit FLAG_NOT_FOCUSABLE hat, kann der Nutzer keine Schlüssel- oder Schaltflächenereignisse an dieses senden.

Kotlin

override fun onCreate(savedInstanceState: Bundle) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_main)
  window.addFlags(WindowManager.LayoutParams.FLAG_FLAG_NOT_FOCUSABLE)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
}

Zeitlimit für Übertragungsempfänger

Ein Broadcast-Empfänger-ANR-Fehler tritt auf, wenn ein Übertragungsempfänger einen zeitgerecht übertragen werden. Für synchrone Empfänger oder Empfänger, die keine goAsync() bedeutet eine Zeitüberschreitung, dass onReceive() in . Für asynchrone Empfänger oder Empfänger, die goAsync() aufrufen, bedeutet ein Zeitlimit dass PendingResult.finish() nicht rechtzeitig aufgerufen wurde.

ANR-Fehler beim Broadcast-Empfänger treten häufig in diesen Threads auf:

  • Hauptthread, wenn das Problem ein langsamer App-Start ist.
  • Thread mit Broadcast-Empfänger, wenn das Problem langsam ist: onReceive()-Code.
  • Broadcast-Worker-Threads senden, wenn das Problem ein langsamer goAsync()-Broadcast-Code ist.

Beachte die folgenden Best Practices, um ANR-Fehler bei Übertragungsempfängern zu vermeiden:

  • Achten Sie darauf, dass die App schnell gestartet wird, da dies im ANR-Zeitlimit berücksichtigt wird, wenn die App mit der Verarbeitung der Übertragung begonnen hat.
  • Wenn goAsync() verwendet wird, achte darauf, dass PendingResult.finish() schnell aufgerufen wird. Dies unterliegt demselben ANR-Zeitlimit wie bei synchronen Übertragungsempfängern.
  • Wenn goAsync() verwendet wird, dürfen die Worker-Threads nicht für oder andere lang andauernde oder blockierende Vorgänge.
  • Verwenden Sie registerReceiver(), um Übertragungsempfänger in einem Nicht-Hauptthread, um zu verhindern, dass der im Hauptthread ausgeführte UI-Code blockiert wird.

Zeiträume für Zeitlimits

Zeitlimits für Broadcast-Empfang hängen davon ab, ob die Vordergrund-Intent-Flag festgelegt ist, und die Plattformversion.

Intent-Typ Android 13 und niedriger Android 14 und höher

Vordergrund-Priorität

FLAG_RECEIVER_FOREGROUND festgelegt)

10 Sekunden

10–20 Sekunden, je nachdem, ob der Prozess zu viel CPU-Leistung beansprucht

Hintergrund-Prioritätsabsicht

(FLAG_RECEIVER_FOREGROUND nicht festgelegt)

60 Sekunden

60 bis 120 Sekunden, je nachdem, ob der Prozess zu viel CPU-Leistung hat

Suchen Sie nach "flg=", um festzustellen, ob das Flag FLAG_RECEIVER_FOREGROUND gesetzt ist. in der ANR-Subjekt und prüfe, ob 0x10000000 vorhanden ist. Wenn dieses Bit gesetzt ist, Für den Intent ist FLAG_RECEIVER_FOREGROUND festgelegt und das Zeitlimit ist daher kürzer.

Beispiel für einen ANR-Fehler mit einem kurzen Broadcast-Timeout (10–20 Sekunden):

Broadcast of Intent { act=android.inent.action.SCREEN_ON flg=0x50200010 }

Beispiel für einen ANR-Fehler mit einem langen Broadcast-Timeout (60–120 Sekunden):

Broadcast of Intent { act=android.intent.action.TIME_SET flg=0x25200010 }

So werden Übertragungszeiten gemessen

Die Messung der Übertragungsdauer beginnt, wenn der Broadcast gesendet wird von system_server an die App und wird beendet, wenn die App die Verarbeitung der Nachricht an alle. Wenn der App-Prozess noch nicht ausgeführt wurde, muss er auch eine kalte innerhalb der ANR-Zeitüberschreitung beginnen. Daher kann ein langsamer App-Start zu ANR-Fehler bei Übertragungsempfängern.

Die folgende Abbildung zeigt die ANR-Zeitachse des Übertragungsempfängers bestimmte App-Prozesse.

<ph type="x-smartling-placeholder">
</ph> Abbildung 3: Die ANR-Zeitachse des Übertragungsempfängers.

Die Messung des ANR-Zeitlimits endet, wenn der Empfänger die Verarbeitung der Nachricht an alle: Wann genau dies geschieht, hängt davon ab, ob es sich um eine synchrone asynchroner Empfänger.

  • Bei synchronen Empfängern wird die Messung beendet, wenn onReceive() zurückgegeben wird.
  • Bei asynchronen Empfängern endet die Messung, wenn PendingResult.finish() wird aufgerufen.
Abbildung 4: Messendpunkte für ANR-Zeitüberschreitungen für synchrone und asynchrone Empfänger.

Häufige Ursachen

Im Folgenden finden Sie einige häufige Ursachen und empfohlene Lösungen für ANR-Fehler bei Übertragungsempfängern.

Ursache Applies to Hintergrund Vorgeschlagene Korrektur
Langsamer App-Start Alle Empfänger Der Kaltstart der App hat zu lange gedauert. Langsamen App-Start optimieren.
onReceive() nicht geplant Alle Empfänger Der Thread des Übertragungsempfängers war mit anderen Aufgaben beschäftigt und konnte nicht Starten Sie die Methode onReceive(). Nicht ausführen lang andauernde Aufgaben im Empfängerthread (oder den Empfänger auf einen dedizierten Thread).
Langsames Speichergerät (onReceive()) Alle Empfänger, aber hauptsächlich synchrone Die Methode onReceive() wurde gestartet, war blockiert oder langsam und wurde daher nicht rechtzeitig abgeschlossen. Langsam optimieren Empfangscode.
Aufgaben für asynchrone Empfänger sind nicht geplant goAsync() Empfänger Die Methode onReceive() hat versucht, eine Arbeit auszuführen in einem blockierten Worker-Thread-Pool, sodass die Arbeit nie begonnen hat. Langsame oder blockierende Anrufe optimieren oder verschiedene Threads für die Übertragung verwenden Workern im Vergleich zu anderen lang andauernden Aufgaben.
Worker sind langsam oder blockiert goAsync() Empfänger Im Worker-Thread ist ein blockierender oder langsamer Vorgang aufgetreten während die Übertragung verarbeitet wird. Also, PendingResult.finish nicht rechtzeitig aufgerufen wurde. Langsamen async-Empfänger optimieren Code.
PendingResult.finish nicht angerufen goAsync() Empfänger Der Aufruf von finish() fehlt im Codepfad. Achten Sie darauf, dass finish() immer aufgerufen wird.

Fehlerbehebung

Anhand der Clustersignatur und des ANR-Berichts können Sie den Thread finden, auf dem der Empfänger ausgeführt wird, und der spezifische Code, der fehlt oder ausgeführt wird, langsam.

Das folgende Flussdiagramm zeigt, wie du den Grund einer Übertragung ermitteln kannst. Empfänger-ANR-Fehler.

<ph type="x-smartling-placeholder">
</ph> Abbildung 5: Fehlerbehebung bei einem ANR-Fehler eines Übertragungsempfängers

Empfängercode finden

In der Google Play Console werden die Empfängerklasse und die Übertragungsabsicht im ANR-Fehler angezeigt Signatur. Suchen Sie nach Folgendem:

  • cmp=<receiver class>
  • act=<broadcast_intent>

Hier ein Beispiel für eine ANR-Signatur eines Übertragungsempfängers:

com.example.app.MyClass.myMethod
Broadcast of Intent { act=android.accounts.LOGIN_ACCOUNTS_CHANGED
cmp=com.example.app/com.example.app.MyAccountReceiver }

Thread suchen, in dem die onReceive()-Methode ausgeführt wird

Wenn Sie mit Context.registerReceiver einen benutzerdefinierten Handler angeben, Es ist der Thread, der diesen Handler ausführt. Andernfalls ist es der Hauptthread.

Beispiel: nicht geplante Aufgaben für asynchrone Empfänger

In diesem Abschnitt wird ein Beispiel für die Fehlerbehebung beim ANR-Fehler eines Übertragungsempfängers beschrieben.

Angenommen, die ANR-Signatur sieht so aus:

com.example.app.MyClass.myMethod
Broadcast of Intent {
act=android.accounts.LOG_ACCOUNTS_CHANGED cmp=com.example.app/com.example.app.MyReceiver }

Laut der Signatur ist der Broadcast-Intent android.accounts.LOG_ACCOUNTS_CHANGED und die Empfängerklasse ist com.example.app.MyReceiver.

Anhand des Empfängercodes können Sie feststellen, dass der Thread-Pool „BG Thread“ [0,1,2,3]" verarbeitet die Übertragung. Ein Blick auf den Stack -Dumps enthalten, können Sie sehen, dass alle vier Hintergrundthreads das gleiche Muster haben: führen sie den blockierenden Aufruf „getDataSync“ aus. Da alle BG-Threads beschäftigt waren, Übertragung konnte nicht rechtzeitig verarbeitet werden. Dies hat zu einem ANR-Fehler geführt.

BG Thread #0 (tid=26) Waiting

at jdk.internal.misc.Unsafe.park(Native method:0)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture:563)
at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture:68)
at com.example.app.getDataSync(<MyClass>:152)

...

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
at com.google.android.libraries.concurrent.AndroidExecutorsModule.lambda$withStrictMode$5(AndroidExecutorsModule:451)
at com.google.android.libraries.concurrent.AndroidExecutorsModule$$ExternalSyntheticLambda8.run(AndroidExecutorsModule:1)
at java.lang.Thread.run(Thread.java:1012)
at com.google.android.libraries.concurrent.ManagedPriorityThread.run(ManagedPriorityThread:34)

There are several approaches to fix the issue:

  • Find out why getDataSync is slow and optimize.
  • Don't run getDataSync on all four BG threads.
  • More generally, ensure that the BG thread pool isn't saturated with long-running operations.
  • Use a dedicated thread pool for goAsync worker tasks.
  • Use an unbounded thread pool instead of the bounded BG thread pool

Example: slow app startup

A slow app startup can cause several types of ANRs, especially broadcast receiver and execute service ANRs. The cause of an ANR is likely slow app startup if you see ActivityThread.handleBindApplication in the main thread stacks.

Execute service timeout

An execute service ANR happens when the app's main thread doesn't start a service in time. Specifically, a service doesn't finish executing onCreate() and onStartCommand() or onBind() within the timeout period.

Default timeout period: 20 seconds for foreground service; 200 seconds for background service. The ANR timeout period includes the app cold start, if necessary, and calls to onCreate(), onBind(), or onStartCommand().

To avoid execute service ANRs, follow these general best practices:

  • Make sure that app startup is fast, since it's counted in the ANR timeout if the app is started to run the service component.
  • Make sure that the service's onCreate(), onStartCommand(), and onBind() methods are fast.
  • Avoid running any slow or blocking operations on the main thread from other components; these operations can prevent a service from starting quickly.

Common causes

The following table lists common causes of execute service ANRs and suggested fixes.

Cause What Suggested fix
Slow app startup The app takes too long to perform a cold start. Optimize slow app start.
Slow onCreate(), onStartCommand(), or onBind() The service component's onCreate(), onStartCommand(), or onBind() method takes too long to execute on the main thread. Optimize slow code. Move slow operations off the critical path where possible.
Not scheduled (main thread blocked before onStart()) The app's main thread is blocked by another component before the service can be started. Move other component's work off the main thread. Optimize other component's blocking code.

How to debug

From the cluster signature and ANR report in Google Play Console or Firebase Crashlytics, you can often determine the cause of the ANR based on what the main thread is doing.

The following flow chart describes how to debug an execute service ANR.

Figure 6. How to debug an execute service ANR.

If you've determined that the execute service ANR is actionable, follow these steps to help resolve the issue:

  1. Find the service component class in the ANR signature. In Google Play Console, the service component class is shown in the ANR signature. In the following example ANR details, it's com.example.app/MyService.

    com.google.common.util.concurrent.Uninterruptibles.awaitUninterruptibly
    Executing service com.example.app/com.example.app.MyService
    
  2. Determine whether the slow or block operation is part of app startup, the service component, or elsewhere by checking for the following important function call(s) in the main threads.

    Function call(s) in main thread stacks What it means
    android.app.ActivityThread.handleBindApplication App was starting up, so the ANR was caused by slow app start.

    <ServiceClass>.onCreate()

    [...]

    android.app.ActivityThread.handleCreateService

    Service was being created, so the ANR was likely caused by slow onCreate() code.

    <ServiceClass>.onBind()

    [...]

    android.app.ActivityThread.handleBindService

    Service was being bound, so the ANR was likely caused by slow onBind() code.

    <ServiceClass>.onStartCommand()

    [...]

    android.app.ActivityThread.handleServiceArgs

    Service was being started, so the ANR was likely caused by slow onStartCommand() code.

    For example, if the onStartCommand() method in the MyService class is slow, the main threads will look like this:

    at com.example.app.MyService.onStartCommand(FooService.java:25)
    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4820)
    at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(unavailable:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2289)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:205)
    at android.os.Looper.loop(Looper.java:294)
    at android.app.ActivityThread.main(ActivityThread.java:8176)
    at java.lang.reflect.Method.invoke(Native method:0)
    

    Wenn Sie keinen der wichtigen Funktionsaufrufe sehen, gibt es ein paar andere Möglichkeiten:

    • Der Dienst wird ausgeführt oder wird heruntergefahren, was bedeutet, dass die Stacks zu spät dran. In diesem Fall können Sie den ANR-Fehler als falsch positives Ergebnis ignorieren.
    • Eine andere App-Komponente wird ausgeführt, zum Beispiel ein Übertragungsempfänger. In dieser wenn der Hauptthread wahrscheinlich in dieser Komponente blockiert ist. wenn der Dienst neu ist.
  3. Wenn Sie einen Funktionsaufruf sehen und feststellen können, wo der ANR-Fehler aufgetreten ist prüfen Sie den Rest des Hauptthread-Stacks, optimieren oder aus dem kritischen Pfad verschieben.

  4. Weitere Informationen zu Diensten finden Sie auf den folgenden Seiten:

    Contentanbieter reagiert nicht

    Ein ANR-Fehler beim Contentanbieter tritt auf, wenn ein Remote-Contentanbieter länger als das Zeitlimit zum Antworten auf eine Abfrage erreicht und beendet wird.

    Standardmäßiges Zeitlimit: Wird vom Contentanbieter mithilfe von ContentProviderClient.setDetectNotResponding Zeitlimit für ANR-Fehler umfasst die Gesamtzeit für die Ausführung einer Abfrage des Remote-Contentanbieters, die beinhaltet den Kaltstart der Remote-App, falls sie noch nicht ausgeführt wurde.

    Beachten Sie die folgenden Best Practices, um ANR-Fehler bei Contentanbietern zu vermeiden:

    • Achten Sie darauf, dass die App schnell gestartet wird, da dies im ANR-Zeitlimit berücksichtigt wird, wenn wird die App gestartet, um den Contentanbieter auszuführen.
    • Stellen Sie sicher, dass die Anfragen des Contentanbieters schnell sind.
    • Führen Sie nicht mehrere blockierende Binder-Aufrufe gleichzeitig aus, die alle die Binder-Threads der App.

    Häufige Ursachen

    In der folgenden Tabelle sind häufige Ursachen für ANR-Fehler bei Contentanbietern sowie Vorschläge für Fehlerbehebungen.

    Ursache Was passiert? Signal Vorgeschlagene Korrektur
    Langsame Anfrage zum Contentanbieter Die Ausführung des Contentanbieters dauert zu lange oder wird blockiert. Der Frame android.content.ContentProvider$Transport.query sich im Binder-Thread befindet. Optimiert die Suchanfrage des Contentanbieters. Herausfinden, was den Binder blockiert Diskussions-Thread.
    Langsamer App-Start Der Start der App des Contentanbieters dauert zu lange. Der Frame ActivityThread.handleBindApplication befindet sich im Bereich im Hauptthread. App-Start optimieren
    Ausschöpfung des Binder-Threads – alle Binder-Threads sind beschäftigt. Alle Binder-Threads sind mit der Verarbeitung anderer synchroner Anfragen beschäftigt, sodass der Der Aufruf des Contentanbieters-Binders kann nicht ausgeführt werden. Die App wird nicht gestartet, alle Binder-Threads sind ausgelastet und der Inhalt nicht ausgeführt wird. Reduzieren Sie die Belastung von Binder-Threads. Sie sollten also weniger synchrone oder weniger Arbeit bei der Verarbeitung eingehender Anrufe zu leisten.

    Fehlerbehebung

    So beheben Sie Fehler bei einem ANR-Fehler eines Contentanbieters mithilfe der Clustersignatur und des ANR-Berichts in Google Play Console oder Firebase Crashlytics, Binder-Threads.

    Im folgenden Flussdiagramm wird beschrieben, wie Sie einen ANR-Fehler eines Contentanbieters beheben:

    <ph type="x-smartling-placeholder">
    </ph> Abbildung 7: Fehlerbehebung bei ANR-Fehlern bei Contentanbietern

    Das folgende Code-Snippet zeigt, wie der Binder-Thread aussieht, wenn er aufgrund einer langsamen Anfrage des Contentanbieters blockiert. In diesem Fall hat der Contentanbieter Abfrage beim Öffnen einer Datenbank auf eine Sperre wartet.

    binder:11300_2 (tid=13) Blocked
    
    Waiting for osm (0x01ab5df9) held by at com.google.common.base.Suppliers$NonSerializableMemoizingSupplier.get(Suppliers:182)
    at com.example.app.MyClass.blockingGetOpenDatabase(FooClass:171)
    [...]
    at com.example.app.MyContentProvider.query(MyContentProvider.java:915)
    at android.content.ContentProvider$Transport.query(ContentProvider.java:292)
    at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:107)
    at android.os.Binder.execTransactInternal(Binder.java:1339)
    at android.os.Binder.execTransact(Binder.java:1275)
    

    Das folgende Code-Snippet zeigt, wie der Hauptthread App-Start ist langsam. In diesem Fall wird die App langsam gestartet, weil Sperren-Konflikt während der Dagger-Initialisierung.

    main (tid=1) Blocked
    
    [...]
    at dagger.internal.DoubleCheck.get(DoubleCheck:51)
    - locked 0x0e33cd2c (a qsn)at dagger.internal.SetFactory.get(SetFactory:126)
    at com.myapp.Bar_Factory.get(Bar_Factory:38)
    [...]
    at com.example.app.MyApplication.onCreate(DocsApplication:203)
    at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1316)
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6991)
    at android.app.ActivityThread.-$$Nest$mhandleBindApplication(unavailable:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2235)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:205)
    at android.os.Looper.loop(Looper.java:294)
    at android.app.ActivityThread.main(ActivityThread.java:8170)
    at java.lang.reflect.Method.invoke(Native method:0)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
    

    Langsame Antwort

    Ein langsamer ANR-Fehler bei einer Jobantwort tritt auf, wenn die App zu lange zum Antworten benötigt. JobService.onStartJob() oder JobService.onStopJob() oder der Vorgang dauert zu lange Erstelle eine Benachrichtigung mit JobService.setNotification(). Dies deutet darauf hin, dass dass der Hauptthread der App keine anderen Aktionen ausführen darf.

    Wenn es ein Problem mit JobService.onStartJob() oder JobService.onStopJob() gibt, prüfen, was im Hauptthread los ist. Wenn es ein Problem mit JobService.setNotification(), rufen Sie sie so schnell wie möglich auf. Erledigen Sie nicht viel Arbeit, bevor Sie die Benachrichtigung senden.

    Mystery-ANRs

    Manchmal ist nicht klar, warum ein ANR-Fehler auftritt, oder es ist nicht ausreichend Informationen zur Fehlerbehebung in der Clustersignatur und im ANR-Bericht. In diesen Fällen können Sie trotzdem feststellen, ob der ANR-Fehler bereinigt und nutzbar.

    Nachrichtenwarteschlange inaktiv oder native PollOnce

    Wenn Sie den Rahmen android.os.MessageQueue.nativePollOnce im gestapelt, weist dies oft darauf hin, dass der vermutete nicht reagierende Thread und auf Looper-Nachrichten warten. ANR-Details in der Google Play Console so aussehen:

    Native method - android.os.MessageQueue.nativePollOnce
    Executing service com.example.app/com.example.app.MyService
    

    Wenn der Hauptthread beispielsweise inaktiv ist, sehen die Stacks so aus:

    "main" tid=1 NativeMain threadIdle
    
    #00  pc 0x00000000000d8b38  /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8)
    #01  pc 0x0000000000019d88  /system/lib64/libutils.so (android::Looper::pollInner(int)+184)
    #02  pc 0x0000000000019c68  /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+112)
    #03  pc 0x000000000011409c  /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce(_JNIEnv*, _jobject*, long, int)+44)
    at android.os.MessageQueue.nativePollOnce (Native method)
    at android.os.MessageQueue.next (MessageQueue.java:339)  at android.os.Looper.loop (Looper.java:208)
    at android.app.ActivityThread.main (ActivityThread.java:8192)
    at java.lang.reflect.Method.invoke (Native method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:626)
    at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1015)
    

    Es gibt mehrere Gründe, warum der vermutlich nicht reagierende Thread inaktiv sein kann:

    • Late-Stack-Dump. Der Thread wies sich in der kurzen Zeit zwischen dem ANR-Auslösung und Stacks, die in Dump umgewandelt werden. Die Latenz von Pixel-Modellen unter Android 13 entspricht ungefähr 100 ms, kann aber 1 s überschreiten. Die Latenz von Pixel Smartphones mit Android 14 beträgt normalerweise unter 10 ms.
    • Falsche Attribution von Threads. Der zum Erstellen der ANR-Signatur verwendete Thread war nicht den tatsächlichen nicht reagierenden Thread, der den ANR-Fehler verursacht hat. Versuchen Sie in diesem Fall, Ermitteln, ob es sich um einen der folgenden ANR-Typen handelt:
    • Systemweites Problem: Der Prozess wurde aufgrund einer hohen Systemauslastung nicht geplant oder ein Problem mit dem Systemserver.

    Keine Stapelframes

    In einigen ANR-Berichten sind die Stacks mit dem ANR-Fehler nicht enthalten. Stack-Dump beim Erstellen des ANR-Berichts ist fehlgeschlagen. Es gibt einige Mögliche Gründe für fehlende Stapelframes:

    • Das Nehmen des Stacks dauert zu lange und es kommt zu einer Zeitüberschreitung.
    • Der Prozess stürzte ab oder wurde abgebrochen, bevor die Stapel übernommen wurden.
    [...]
    
    --- CriticalEventLog ---
    capacity: 20
    timestamp_ms: 1666030897753
    window_ms: 300000
    
    libdebuggerd_client: failed to read status response from tombstoned: timeout reached?
    
    ----- Waiting Channels: pid 7068 at 2022-10-18 02:21:37.<US_SOCIAL_SECURITY_NUMBER>+0800 -----
    
    [...]
    

    ANR-Fehler ohne Stackframes können nicht über die Clustersignatur oder den ANR-Fehler verarbeitet werden Bericht. Sehen Sie sich zum Debuggen andere Cluster für die Anwendung an, da ein großes Problem vorliegt. hat es in der Regel einen eigenen Cluster, in dem Stack-Frames vorhanden sind. Sie können sich auch Perfetto-Traces ansehen.

    Bekannte Probleme

    Einen Timer für die Fertigstellung Ihrer App einstellen vor dem Auslösen eines ANR-Fehlers unter Umständen verwendet das System die asynchrone Überwachung von ANR-Fehlern.