Questo documento mostra come identificare il thread che non risponde in uno stack ANR il dump. Il thread che non risponde varia in base al tipo di errore ANR, come mostrato di seguito tabella.
Tipo di ANR | Il thread non risponde |
---|---|
Invio dell'input | Thread principale |
Invio dell'input senza finestra attiva | Thread principale. In genere questo tipo di errore ANR non è causato da un errore . |
Broadcast receiver (sincrono) | Thread in esecuzione
onReceive() .
Questo è il thread principale, a meno che non venga usato un gestore personalizzato su un thread non principale
specificato utilizzando
Context.registerReceiver . |
Broadcast receiver (asincrono) | Controlla il codice per vedere quale thread o pool di thread è responsabile
che si occupa di elaborare la trasmissione
goAsync
. |
Esecuzione del timeout del servizio in corso... | Thread principale |
Inizio servizio in primo piano | Thread principale |
Il fornitore di contenuti non risponde | Una di queste soglie:
|
Nessuna risposta a
onStartJob
o
onStopJob |
Thread principale |
A volte il thread non risponde per una causa principale in un thread diverso o processo. Il thread potrebbe non rispondere a causa dell'attesa di quanto segue:
- Un blocco mantenuto da un altro thread.
- Una chiamata a binder lenta a un altro processo.
Cause comuni della mancata risposta dei thread
Di seguito sono riportate le cause comuni della mancata risposta dei thread.
Chiamata a Binder lenta
Sebbene la maggior parte delle chiamate a binder sia veloce, la long tail può risultare molto lenta. Questo è più probabile che si verifichi se il dispositivo viene caricato o se viene rallentati, ad esempio a causa del conflitto di blocchi, molte chiamate a Binder in arrivo o Timeout (HAL).
Puoi risolvere il problema spostando le chiamate a binder sincrone nei thread in background ove possibile. Se la chiamata deve avvenire sul thread principale, scopri perché è lenta. Il modo migliore per farlo è tramite le tracce Perfetto.
Cerca BinderProxy.transactNative
o Binderproxy.transact
nell'elenco filtri.
Ciò significa che è in corso una chiamata a raccoglitore. Segui queste due righe, puoi vedere
viene chiamata l'API binder. Nell'esempio seguente, la chiamata è
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)
...
Molte chiamate a binder consecutive
L'esecuzione di molte chiamate a binder consecutive in un loop stretto può bloccare un thread per per un lungo periodo.
Un I/O che blocca
Non bloccare mai l'I/O sul thread principale. Questo è un anti-pattern.
Conflitto blocco
Se un thread viene bloccato durante l'acquisizione di un blocco, potrebbe verificarsi un errore ANR.
L'esempio seguente mostra che il thread principale è bloccato durante il tentativo di acquisire un blocco:
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)
[...]
Il thread di blocco sta inviando una richiesta HTTP per scaricare un video:
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)
[...]
Cornice costosa
Eseguire il rendering di troppi elementi in un solo frame può far sì che il thread principale non risponde per la durata del frame, come segue:
- Rendering di molti elementi non necessari al di fuori dello schermo.
- Utilizzo di un algoritmo inefficiente, come
O(n^2)
, durante il rendering di molte UI elementi.
Bloccata da un altro componente
Se un altro componente, come un broadcast receiver, blocca il thread principale per più di cinque secondi, può causare errori ANR di invio degli input e gravi jank.
Evita di svolgere operazioni complesse sul thread principale nei componenti dell'app. Esegui trasmissione su un thread diverso, quando possibile.