In diesem Dokument wird gezeigt, wie Sie den nicht reagierenden Thread in einem ANR-Stack identifizieren. Dump. Der nicht reagierende Thread variiert je nach Art des ANR-Fehlers, wie unten dargestellt .
ANR-Typ | Thread reagiert nicht |
---|---|
Eingabeweiterleitung | Hauptthread |
Eingabeweiterleitung – kein fokussiertes Fenster | Hauptthread Diese Art von ANR-Fehler wird normalerweise nicht durch eine blockierte Diskussions-Thread. |
Übertragungsempfänger (synchron) | Thread wird ausgeführt
onReceive()
Dies ist der Hauptthread, es sei denn, ein benutzerdefinierter Handler für einen Nicht-Hauptthread
angegeben mit
Context.registerReceiver |
Übertragungsempfänger (asynchron) | Überprüfen Sie den Code, um zu sehen, welcher Thread oder welcher Thread-Pool
die Übertragung nach der Veröffentlichung
goAsync
aufgerufen wird. |
Zeitlimit für Dienstausführung | Hauptthread |
Start des Dienstes im Vordergrund | Hauptthread |
Contentanbieter reagiert nicht | Dazu haben Sie zwei Möglichkeiten:
<ph type="x-smartling-placeholder">
|
Keine Antwort auf
onStartJob
oder
onStopJob |
Hauptthread |
Manchmal reagiert der Thread aufgrund einer Ursache in einem anderen Thread nicht oder Prozess zu verstehen. Der Thread reagiert möglicherweise nicht, weil auf Folgendes gewartet wird:
- Eine Sperre, die von einem anderen Thread gehalten wird.
- Ein langsamer Binder ruft einen anderen Prozess auf.
Häufige Ursachen für nicht reagierende Threads
Wenn Threads nicht reagieren, kann dies folgende Ursachen haben:
Langsamer Binder-Aufruf
Obwohl die meisten Binder-Aufrufe schnell sind, kann das lange Ende sehr langsam sein. Dies ist häufiger, wenn das Gerät geladen oder der Binder-Antwort-Thread langsam, z. B. durch Schlosskonflikt, viele eingehende Binder-Anrufe oder Hardware HAL-Zeitlimit (Abstraktionsschicht).
Sie können dies lösen, indem Sie synchrone Binder-Aufrufe in Hintergrundthreads verschieben. wenn möglich. Wenn der Anruf im Hauptthread erfolgen muss, finden Sie heraus, warum der Anruf ist langsam. Dazu verwenden Sie am besten Perfetto-Traces.
Suchen Sie in den Stacks nach BinderProxy.transactNative
oder Binderproxy.transact
.
Dies bedeutet, dass ein Binder-Aufruf stattfindet. Diesen beiden Zeilen folgen Sie,
die aufgerufene binder API. Im folgenden Beispiel soll der Aufruf
IAccessibilityManager.addClient
main tid=123
...
android.os.BinderProxy.transactNative (Native method)
android.os.BinderProxy.transact (BinderProxy.java:568)
android.view.accessibility.IAccessibilityManager$Stub$Proxy.addClient (IAccessibilityManager.java:599)
...
Viele aufeinanderfolgende Binder-Aufrufe
Wenn Sie viele aufeinanderfolgende Binder-Aufrufe in einer engen Schleife durchführen, kann ein Thread über einen längeren Zeitraum.
Eine blockierende E/A
Führen Sie niemals eine blockierende E/A im Hauptthread durch. Dies ist ein Anti-Pattern.
Konflikt durch Sperre
Wenn ein Thread beim Erhalt einer Sperre blockiert wird, kann dies zu einem ANR-Fehler führen.
Das folgende Beispiel zeigt, dass der Hauptthread blockiert wird, wenn versucht wird, einen Schloss:
main (tid=1) Blocked
Waiting for com.example.android.apps.foo.BarCache (0x07d657b7) held by
ptz-rcs-28-EDITOR_REMOTE_VIDEO_DOWNLOAD
[...]
at android.app.ActivityThread.handleStopActivity(ActivityThread.java:5412)
[...]
Der blockierende Thread sendet eine HTTP-Anfrage zum Herunterladen eines Videos:
ptz-rcs-28-EDITOR_REMOTE_VIDEO_DOWNLOAD (tid=110) Waiting
at jdk.internal.misc.Unsafe.park(Native method:0)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:715)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1047)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:230)
at com.example.android.apps.foo.HttpRequest.execute(HttpRequest:136)
at com.example.android.apps.foo$Task$VideoLoadTask.downloadVideoToFile(RequestExecutor:711)
[...]
Teurer Frame
Wenn Sie zu viele Dinge in einem einzelnen Frame rendern, kann dies dazu führen, dass der Hauptthread nicht reagieren, wie z. B.:
- Viele unnötige Elemente werden gerendert, die nicht auf dem Bildschirm zu sehen sind.
- Verwendung eines ineffizienten Algorithmus wie
O(n^2)
beim Rendern vieler UI-Elemente Elemente.
Durch andere Komponente blockiert
Wenn eine andere Komponente, z. B. ein Übertragungsempfänger, den Hauptthread länger als fünf Sekunden dauern, kann dies zu ANR-Fehlern beim Senden von Eingaben und zu schwerwiegenden Verzögerungen führen.
Vermeiden Sie umfangreiche Arbeiten am Hauptthread in App-Komponenten. Broadcast ausführen an einen anderen Thread senden.