ANR-Fehler diagnostizieren und beheben

Wenn der UI-Thread einer Android-App zu lange blockiert ist, sendet das System den ANR-Fehler „App antwortet nicht“. Auf dieser Seite werden die verschiedenen Arten von ANR-Fehlern, ihre Diagnose und Vorschläge zur Behebung beschrieben. Alle aufgeführten Standardzeiträume für Zeitüberschreitungen gelten für AOSP- und Pixel-Geräte. Diese Zeiten können je nach OEM variieren.

Beachten Sie, dass es bei der Ermittlung der Ursache von ANR-Fehlern hilfreich ist, zwischen System- und Anwendungsproblemen zu unterscheiden.

Wenn das System nicht ordnungsgemäß funktioniert, können die folgenden Probleme ANR-Fehler verursachen:

  • Vorübergehende Probleme auf dem Systemserver führen dazu, dass schnelle Binder-Aufrufe in der Regel langsam sind.
  • Probleme mit dem Systemserver und eine hohe Gerätelast führen dazu, dass Anwendungsthreads nicht geplant werden.

Sofern verfügbar, können Sie Perfetto-Traces verwenden, um zwischen System- und Anwendungsproblemen zu unterscheiden:

  • Prüfen Sie, ob der Hauptthread der Anwendung geplant ist. Sehen Sie sich dazu den Thread-Status-Track in Perfetto an, um zu sehen, ob er ausgeführt wird oder ausgeführt werden kann.
  • Suchen Sie in den system_server-Threads nach Problemen wie Sperrenkonflikten.
  • Sehen Sie sich bei langsamen Binder-Aufrufen den Antwortthread an, falls vorhanden, um zu sehen, warum er langsam ist.

Zeitlimit für Eingabeweiterleitung

ANR-Fehler bei der Eingabeweiterleitung treten auf, wenn der Hauptthread der App nicht rechtzeitig auf ein Eingabeereignis reagiert, z. B. eine Wischbewegung oder eine Tastenbetätigung. Da sich die Anwendung im Vordergrund befindet, wenn Zeitüberschreitungen bei der Eingabeweiterleitung auftreten, sind diese für den Nutzer fast immer sichtbar und es ist sehr wichtig, das Problem zu beheben.

Standardmäßiges Zeitlimit: 5 Sekunden.

ANR-Fehler bei der Eingabeweiterleitung werden normalerweise durch Probleme im Hauptthread verursacht. Wenn der Hauptthread blockiert wurde, während er auf eine Sperre wartet, kann auch der Halter-Thread einbezogen werden.

Halten Sie sich an die folgenden Best Practices, um ANR-Fehler durch Eingabeweiterleitungen zu vermeiden:

  • Führen Sie im Hauptthread keine blockierenden oder lang andauernden Vorgänge aus. Sie können StrictMode verwenden, um versehentliche Aktivitäten im Hauptthread abzufangen.
  • Minimieren Sie Konflikte durch Sperren zwischen dem Hauptthread und anderen Threads.
  • Minimieren Sie Arbeiten im Hauptthread, die nicht über die Benutzeroberfläche erfolgen, z. B. bei der Verarbeitung von Broadcasts oder beim Ausführen von Diensten.

Häufige Ursachen

Im Folgenden finden Sie einige häufige Ursachen und empfohlene Fehlerbehebungen für ANR-Fehler bei der Eingabeweiterleitung.

Ursache Ablauf Lösungsvorschläge
Langsamer Binder-Aufruf Der Hauptthread führt einen langen synchronen Binderaufruf aus. Entfernen Sie den Aufruf aus dem Hauptthread oder versuchen Sie, ihn zu optimieren, wenn Sie Inhaber der API sind.
Viele aufeinanderfolgende Binder-Aufrufe Der Hauptthread führt viele aufeinanderfolgende synchrone Binder-Aufrufe aus. Führe keine Binder-Aufrufe in einer engen Schleife durch.
E/A blockieren Der Hauptthread blockiert E/A-Aufrufe, z. B. den Datenbank- oder Netzwerkzugriff. Alle blockierenden E/A-Vorgänge aus dem Hauptthread verschieben.
Sperrungskonflikt Der Hauptthread ist blockiert und wartet auf eine Sperre. Reduzieren Sie Konflikte durch Sperren zwischen dem Hauptthread und dem anderen Thread. Optimieren Sie langsamen Code im anderen Thread.
Teiger Frame Zu viel Rendering in einem einzelnen Frame, was zu einer erheblichen Verzögerung führt Weniger Arbeitsaufwand für den Rahmen. Verwenden Sie keine n2-Algorithmen. Verwenden Sie effiziente Komponenten für Dinge wie Scrollen oder Paging, z. B. die Jetpack-Paging-Bibliothek.
Von anderer Komponente blockiert Eine andere Komponente, z. B. ein Broadcast-Empfänger, wird ausgeführt und blockiert den Hauptthread. Verschieben Sie Aufgaben, die nicht auf der Benutzeroberfläche basieren, so weit wie möglich aus dem Hauptthread. Führen Sie Broadcast-Empfänger in einem anderen Thread aus.
GPU hängt Ein GPU-Ausfall ist ein System- oder Hardwareproblem, das dazu führt, dass das Rendering blockiert und folglich ein ANR-Fehler für die Eingabe ausgelöst wird. Leider gibt es in der App normalerweise keine Fehlerbehebungen. Wenden Sie sich zur Fehlerbehebung nach Möglichkeit an das Hardwareteam.

Fehlerbehebung

Beginnen Sie mit dem Debugging, indem Sie sich die ANR-Clustersignatur in der Google Play Console oder Firebase Crashlytics ansehen. Der Cluster enthält normalerweise die obersten Frames, die vermutlich den ANR-Fehler verursachen.

Das folgende Flussdiagramm zeigt, wie Sie die Ursache für die Weiterleitung eines ANR-Fehlers bei einer Eingabezeitüberschreitung ermitteln.

Abbildung 1: So beheben Sie einen ANR-Fehler bei einer Eingabeweiterleitung.

Mit Play Vitals kannst du einige der folgenden Ursachen für ANR-Fehler erkennen und beheben. Wenn z. B. in den Vitals-Daten ein ANR-Fehler aufgrund eines Konflikts durch eine Sperre erkannt wird, können das Problem und die empfohlene Problembehebung im Abschnitt Statistiken zu ANR-Fehlern zusammengefasst werden.

Abbildung 2. Play Vitals-ANR-Erkennung.

Kein Fenster im Fokus

Während Ereignisse wie Berührungen basierend auf Treffertests direkt an das relevante Fenster gesendet werden, benötigen Ereignisse wie Schlüssel ein Ziel. Dieses Ziel wird als fokussiertes Fenster bezeichnet. Es gibt nur ein fokussiertes Fenster pro Anzeige. Normalerweise ist dies das Fenster, mit dem der Nutzer gerade interagiert. Wenn ein fokussiertes Fenster nicht gefunden werden kann, löst die Eingabe einen ANR-Fehler ohne Fokusfenster aus. Ein ANR-Fehler ohne Fokusfenster ist eine Art von ANR-Fehler auf der Eingabeweiterleitung.

Standardmäßiges Zeitlimit: 5 Sekunden.

Häufige Ursachen

ANR-Fehler bei nicht fokussierten Fenstern werden in der Regel durch eines der folgenden Probleme verursacht:

  • Die App erledigt 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 gekennzeichnet ist, kann der Nutzer keine Schlüssel- oder Schaltflächenereignisse an dieses Fenster 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 ANR-Fehler bei einem Übertragungsempfänger tritt auf, wenn ein Empfänger eine Übertragung nicht rechtzeitig verarbeitet. Bei synchronen Empfängern oder Empfängern, die goAync() nicht aufrufen, bedeutet ein Zeitlimit, dass onReceive() nicht rechtzeitig abgeschlossen wurde. Bei asynchronen Empfängern oder Empfängern, die goAsync() aufrufen, bedeutet ein Zeitlimit, dass PendingResult.finish() nicht rechtzeitig aufgerufen wurde.

ANR-Fehler bei Übertragungsempfängern treten häufig in diesen Threads auf:

  • Hauptthread, wenn das Problem durch einen langsamen App-Start verursacht wird.
  • Thread führt den Broadcast-Empfänger aus, wenn das Problem ein langsamer onReceive()-Code ist.
  • Broadcast-Worker-Threads, wenn das Problem ein langsamer goAsync()-Broadcast-Code ist.

Mit den folgenden Best Practices kannst du ANR-Fehler bei Broadcast-Empfängern vermeiden:

  • Achten Sie darauf, dass die App schnell startet, da dies im ANR-Zeitlimit berücksichtigt wird, wenn die App mit der Verarbeitung des Broadcasts gestartet wird.
  • Wenn goAsync() verwendet wird, muss PendingResult.finish() schnell aufgerufen werden. Dies unterliegt demselben ANR-Zeitlimit wie bei synchronen Sendeempfängern.
  • Wenn goAsync() verwendet wird, achten Sie darauf, dass die Worker-Threads nicht für andere lang andauernde oder blockierende Vorgänge freigegeben werden.
  • Erwägen Sie die Verwendung von registerReceiver(), um Übertragungsempfänger in einem Nicht-Hauptthread auszuführen. So wird verhindert, dass UI-Code blockiert wird, der im Hauptthread ausgeführt wird.

Zeitüberschreitung

Zeitüberschreitungszeiträume beim Empfang von Übertragungen hängen davon ab, ob das Flag für den Vordergrund-Intent festgelegt ist, und von der Plattformversion.

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

Intent mit Priorität im Vordergrund

(FLAG_RECEIVER_FOREGROUND festgelegt)

10 Sekunden

10 bis 20 Sekunden, je nachdem, ob der Prozess zu wenig CPU-Kapazität hat

Hintergrundprioritäts-Intent

(FLAG_RECEIVER_FOREGROUND nicht festgelegt)

60 Sekunden

60 bis 120 Sekunden, je nachdem, ob der Prozess zu wenig CPU-Kapazität hat

Wenn Sie wissen möchten, ob das Flag FLAG_RECEIVER_FOREGROUND gesetzt ist, suchen Sie im ANR-Betreff nach „flg=“ und prüfen Sie, ob 0x10000000 vorhanden ist. Wenn dieses Bit gesetzt ist, ist für den Intent FLAG_RECEIVER_FOREGROUND festgelegt, wodurch das Zeitlimit kürzer wird.

Beispiel für einen ANR-Betreff mit einem kurzen Zeitlimit für die Übertragung (10–20 Sekunden):

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

Beispiel für ein ANR-Thema mit einem langen Sendezeitlimit (60–120 Sekunden):

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

So werden Übertragungszeiten gemessen

Die Messung der Übertragungsdauer beginnt, wenn die Übertragung von system_server an die Anwendung gesendet wird, und endet, wenn die Anwendung die Übertragung beendet hat. Wenn der Anwendungsprozess noch nicht ausgeführt wurde, muss innerhalb des ANR-Zeitlimits ein Kaltstart erfolgen. Daher kann ein langsamer App-Start zu ANR-Fehlern bei Übertragungsempfängern führen.

Die folgende Abbildung zeigt, wie die Zeitachse des ANR-Fehlers beim Rundfunkempfänger auf bestimmte App-Prozesse abgestimmt ist.

Abbildung 3: Die ANR-Zeitachse des Senders.

Die ANR-Zeitüberschreitungsmessung endet, wenn der Empfänger die Verarbeitung der Übertragung beendet hat. Wann genau dies geschieht, hängt davon ab, ob es sich um einen synchronen oder einen asynchronen Empfänger handelt.

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

Häufige Ursachen

Im Folgenden finden Sie einige häufige Ursachen und empfohlene Fehlerbehebungen für ANR-Fehler bei Rundfunkempfängern.

Ursache Gilt für: Hintergrund Korrekturvorschlag
Langsamer App-Start Alle Empfänger Die App hat zu lange für einen Kaltstart gedauert. Langsamen App-Start optimieren.
onReceive() nicht geplant Alle Empfänger Der Thread des Broadcast-Empfängers war mit anderen Aufgaben beschäftigt und konnte die Methode onReceive() nicht starten. Führen Sie keine Aufgaben mit langer Ausführungszeit im Empfängerthread aus (und verschieben Sie den Empfänger nicht in einen dedizierten Thread).
Langsames Speichergerät (onReceive()) Alle Empfänger, aber hauptsächlich synchrone Empfänger Die Methode onReceive() wurde gestartet, war aber blockiert oder langsam und wurde daher nicht rechtzeitig abgeschlossen. Optimiert den Code für langsamen Empfänger.
Aufgaben für asynchrone Empfänger nicht geplant goAsync() Empfänger Die Methode onReceive() hat versucht, Arbeit für einen blockierten Worker-Thread-Pool auszuführen, sodass die Arbeit nie gestartet wurde. Optimieren Sie langsame oder blockierende Aufrufe oder verwenden Sie für Broadcast-Worker andere Threads als für andere lang andauernde Aufgaben.
Worker langsam oder blockiert goAsync() Empfänger Während der Verarbeitung des Broadcasts ist ein blockierender oder langsamer Vorgang im Worker-Thread-Pool aufgetreten. Daher wurde PendingResult.finish nicht rechtzeitig aufgerufen. Langsamen async-Empfängercode optimieren.
Sie haben vergessen, PendingResult.finish anzurufen 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, in dem der Empfänger ausgeführt wird, und dann den spezifischen Code, der fehlt oder langsam ausgeführt wird.

Das folgende Flussdiagramm zeigt, wie du die Ursache eines ANR-Fehlers bei einem Übertragungsempfänger ermitteln kannst.

Abbildung 5: So behebst du Fehler bei einem ANR-Fehler bei einem Rundfunkempfänger.

Empfängercode finden

In der Google Play Console werden die Empfängerklasse und der Übertragungs-Intent in der ANR-Signatur angezeigt. Achten Sie auf Folgendes:

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

Hier ist ein Beispiel für eine ANR-Signatur bei einem Rundfunkempfänger:

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, ist dies der Thread, der diesen Handler ausführt. Andernfalls ist es der Hauptthread.

Beispiel: nicht geplante asynchrone Empfängeraufgaben

In diesem Abschnitt wird ein Beispiel für die Fehlerbehebung bei einem ANR-Fehler bei einem Übertragungsempfänger 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 }

Anhand der Signatur sieht es so aus, als ob der Übertragungs-Intent android.accounts.LOG_ACCOUNTS_CHANGED und die Empfängerklasse com.example.app.MyReceiver ist.

Anhand des Empfängercodes können Sie feststellen, dass der Thread-Pool „BG Thread [0,1,2,3]“ die Hauptarbeit für die Verarbeitung dieses Broadcasts übernimmt. In den Stack-Dumps sehen Sie, dass alle vier Hintergrundthreads (BG) das gleiche Muster haben: Sie führen den blockierenden Aufruf getDataSync aus. Da alle BG-Threads beschäftigt waren, konnte die Übertragung nicht rechtzeitig verarbeitet werden, was zu einem ANR-Fehler führte.

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 einige weitere Möglichkeiten:

    • Der Dienst wird ausgeführt oder wird heruntergefahren, was bedeutet, dass die Stacks zu spät genommen werden. In diesem Fall kannst du den ANR-Fehler als falsch positives Ergebnis ignorieren.
    • Eine andere App-Komponente wird ausgeführt, z. B. ein Sendeempfänger. In diesem Fall wird der Hauptthread wahrscheinlich in dieser Komponente blockiert, wodurch der Dienst nicht gestartet werden kann.
  3. Wenn Sie einen wichtigen Funktionsaufruf sehen und feststellen können, wo der ANR-Fehler im Allgemeinen auftritt, prüfen Sie die übrigen Hauptthread-Stacks, um den langsamen Vorgang zu finden und ihn zu optimieren oder aus dem kritischen Pfad zu verschieben.

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

    Contentanbieter antwortet nicht

    Ein Inhaltsanbieter-ANR-Fehler tritt auf, wenn ein Remote-Inhaltsanbieter zum Antworten auf eine Abfrage länger als das Zeitlimit benötigt und gelöscht wird.

    Standardmäßiges Zeitlimit: Dieses wird vom Contentanbieter mit ContentProviderClient.setDetectNotResponding festgelegt. Das ANR-Zeitlimit umfasst die Gesamtzeit für die Ausführung einer Abfrage des Remote-Inhaltsanbieters, einschließlich des Kaltstarts der Remote-App, sofern sie noch nicht ausgeführt wurde.

    Halten Sie sich an die folgenden Best Practices, um ANR-Fehler bei Contentanbietern zu vermeiden:

    • Die App muss schnell gestartet werden, da dies im ANR-Zeitlimit gezählt wird, wenn die App mit der Ausführung des Contentanbieters gestartet wird.
    • Achten Sie darauf, dass die Anfragen des Contentanbieters schnell sind.
    • Führen Sie nicht viele gleichzeitige Binderaufrufe aus, die alle Binder-Threads der Anwendung blockieren könnten.

    Häufige Ursachen

    In der folgenden Tabelle sind häufige Ursachen von ANR-Fehlern bei Contentanbietern und Lösungsvorschläge aufgeführt.

    Ursache Ablauf Signal Korrekturvorschlag
    Langsame Anfrage an Contentanbieter Die Ausführung des Contentanbieters dauert zu lange oder wird blockiert. Der Frame android.content.ContentProvider$Transport.query befindet sich im Binder-Thread. Contentanbieter-Suchanfrage optimieren Finden Sie heraus, was den Binder-Thread blockiert.
    Langsamer App-Start Das Starten der App des Contentanbieters dauert zu lange. Der Frame ActivityThread.handleBindApplication befindet sich im Hauptthread. App-Start-ups optimieren
    Erschöpfung der Binder-Threads – alle Binder-Threads sind beschäftigt Alle Binder-Threads sind damit beschäftigt, andere synchrone Anfragen zu bedienen, sodass der Binderaufruf des Contentanbieters nicht ausgeführt werden kann. Die Anwendung wird nicht gestartet, alle Binder-Threads sind ausgelastet und der Inhaltsanbieter wird nicht ausgeführt. Reduzieren Sie die Belastung der Binder-Threads. Das heißt, Sie müssen weniger synchrone ausgehende Binder-Aufrufe ausführen oder weniger Arbeit bei der Verarbeitung eingehender Anrufe erledigen.

    Fehlerbehebung

    Wenn Sie einen ANR-Fehler eines Contentanbieters mithilfe der Clustersignatur und des ANR-Berichts in der Google Play Console oder Firebase Crashlytics beheben möchten, prüfen Sie, was der Hauptthread und die Binder-Threads tun.

    Im folgenden Flussdiagramm wird die Fehlerbehebung für einen Contentanbieter-ANR-Fehler beschrieben:

    Abbildung 7. So beheben Sie einen ANR-Fehler eines Contentanbieters.

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

    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 aussieht, wenn er aufgrund eines langsamen Anwendungsstarts blockiert ist. In diesem Fall ist der Anwendungsstart aufgrund von Sperrenkonflikten während der Dolggerinitialisierung langsam.

    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 Jobantwort

    Ein ANR-Fehler bei einer langsamen Jobantwort tritt auf, wenn die Anwendung zu lange braucht, um auf JobService.onStartJob() oder JobService.onStopJob() zu reagieren, oder wenn es zu lange dauert, eine Benachrichtigung mit JobService.setNotification() zu senden. Dies deutet darauf hin, dass der Hauptthread der App für andere Zwecke blockiert ist.

    Bei einem Problem mit JobService.onStartJob() oder JobService.onStopJob() sehen Sie nach, was im Hauptthread passiert. Wenn es sich um ein Problem mit JobService.setNotification() handelt, rufe es 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 sind nicht genügend Informationen im Clustersignatur- und ANR-Bericht vorhanden, um den Fehler zu beheben. In diesen Fällen können Sie dennoch einige Schritte unternehmen, um festzustellen, ob der ANR-Fehler behoben werden kann.

    Nachrichtenwarteschlange nicht aktiv oder nativePollOnce

    Wenn Sie den Frame android.os.MessageQueue.nativePollOnce in den Stapeln sehen, weist dies häufig darauf hin, dass der vermutete nicht reagierende Thread tatsächlich inaktiv war und auf Looper-Nachrichten gewartet hat. In der Google Play Console sehen die ANR-Details so aus:

    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 vermutete nicht reagierende Thread inaktiv ist:

    • Late Stack-Dump Der Thread wurde während der kurzen Zeitspanne zwischen dem Auslösen des ANR-Fehlers und den gespeicherten Stacks wiederhergestellt. Die Latenz in Pixel-Modellen beträgt unter Android 13 etwa 100 ms, kann aber auch mehr als 1 s betragen. Die Latenz bei Pixel unter Android 14 liegt normalerweise unter 10 ms.
    • Falsche Attribution des Threads. Der zum Erstellen der ANR-Signatur verwendete Thread war nicht der eigentliche nicht reagierende Thread, der den ANR-Fehler verursacht hat. Versuchen Sie in diesem Fall festzustellen, ob der ANR-Fehler einen der folgenden Typen hat:
    • Systemweites Problem. Der Prozess wurde aufgrund einer hohen Systemauslastung oder eines Fehlers auf dem Systemserver nicht geplant.

    Keine Stackframes

    Einige ANR-Berichte enthalten die Stacks mit dem ANR-Fehler nicht. Das bedeutet, dass der Stack-Dumping beim Erstellen des ANR-Berichts fehlgeschlagen ist. Es gibt einige mögliche Gründe für fehlende Stackframes:

    • Die Erstellung des Stapels dauert zu lange und es kommt zu einer Zeitüberschreitung.
    • Der Prozess war oder wurde abgebrochen, bevor die Stapel entnommen 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 Stack-Frames können nicht über die Clustersignatur oder den ANR-Bericht verarbeitet werden. Sehen Sie sich zum Debuggen andere Cluster für die Anwendung an. Wenn ein Problem groß genug ist, hat es normalerweise einen eigenen Cluster mit Stapelframes. Alternativ können Sie sich Perfetto-Traces ansehen.

    Bekannte Probleme

    Einen Timer im App-Prozess beizubehalten, um die Broadcast-Verarbeitung abzuschließen, bevor ein ANR-Trigger ausgelöst wird, da das System ANR-Fehler asynchron überwacht.