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.
![](https://developer.android.com/static/topic/performance/images/debug-input-dispatch-anr.png?authuser=6&hl=de)
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.
![](https://developer.android.com/static/topic/performance/images/play-vitals-anr-detection.png?authuser=6&hl=de)
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, dassPendingResult.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
|
10 Sekunden |
10–20 Sekunden, je nachdem, ob der Prozess zu viel CPU-Leistung beansprucht |
Hintergrund-Prioritätsabsicht ( |
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.
![](https://developer.android.com/static/topic/performance/images/broadcast-receiver-anr-timeline.png?authuser=6&hl=de)
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.
![](https://developer.android.com/static/topic/performance/images/sync-async-measurement-end.png?authuser=6&hl=de)
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.
![](https://developer.android.com/static/topic/performance/images/debug-broadcast-receiver-timeout-anr.png?authuser=6&hl=de)
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()
, andonBind()
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.
![](https://developer.android.com/static/topic/performance/images/debug-execute-service-anr.png?authuser=6&hl=de)
If you've determined that the execute service ANR is actionable, follow these steps to help resolve the issue:
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
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 theMyService
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.
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.
- 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.
- 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.
- 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.
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:
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:
![](https://developer.android.com/static/topic/performance/images/debug-content-provider-anr.png?authuser=6&hl=de)
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:
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:
[...]
--- 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.