Когда поток пользовательского интерфейса приложения Android блокируется слишком долго, система отправляет ошибку «Приложение не отвечает» (ANR). На этой странице описаны различные типы ошибок ANR, способы их диагностики и рекомендации по их устранению. Все указанные диапазоны времени ожидания по умолчанию относятся к устройствам AOSP и Pixel; это время может варьироваться в зависимости от OEM.
Имейте в виду, что при определении причины ошибок ANR полезно различать проблемы системы и приложения.
Когда система находится в плохом состоянии, следующие проблемы могут вызвать ошибки ANR:
- Временные проблемы на системном сервере обычно приводят к замедлению быстрых вызовов связующих.
- Проблемы с системным сервером и высокая нагрузка на устройство приводят к тому, что потоки приложений не планируются.
Если это возможно, хороший способ отличить проблемы системы и приложения — использовать трассировки Perfetto :
- Узнайте, запланирован ли основной поток приложения, просмотрев дорожку состояния потока в Perfetto, чтобы узнать, запущен ли он или работоспособен.
- Просмотрите потоки
system_server
на наличие таких проблем, как конфликт блокировок. - Для медленных вызовов связывания просмотрите цепочку ответов, если она есть, чтобы понять, почему она медленная.
Тайм-аут отправки ввода
Ошибки ANR при отправке ввода возникают, когда основной поток приложения не отвечает вовремя на событие ввода, такое как пролистывание или нажатие клавиши. Поскольку приложение находится на переднем плане, когда происходят тайм-ауты отправки ввода, они почти всегда видны пользователю и очень важно их минимизировать.
Период ожидания по умолчанию : 5 секунд.
Ошибки ANR при отправке ввода обычно вызваны проблемами в основном потоке. Если основной поток был заблокирован в ожидании получения блокировки, также может быть задействован поток-держатель.
Чтобы избежать ошибок ANR при отправке ввода, следуйте этим рекомендациям:
- Не выполняйте блокирующие или длительные операции в основном потоке. Рассмотрите возможность использования
StrictMode
для обнаружения случайных действий в основном потоке. - Минимизируйте конфликт блокировок между основным потоком и другими потоками.
- Сведите к минимуму работу, не связанную с пользовательским интерфейсом, в основном потоке, например, при обработке широковещательных рассылок или запуске служб.
Распространенные причины
Ниже приведены некоторые распространенные причины и предлагаемые исправления ошибок ANR при отправке ввода.
Причина | Что происходит | Предлагаемые исправления |
---|---|---|
Медленный звонок связующего | Основной поток выполняет длинный синхронный вызов связывателя. | Переместите вызов из основного потока или попробуйте оптимизировать вызов, если у вас есть API. |
Множество последовательных вызовов связующего | Главный поток выполняет множество последовательных синхронных вызовов связующего. | Не выполняйте вызовы связующих в узком цикле. |
Блокировка ввода-вывода | Главный поток выполняет блокирующий вызов ввода-вывода, например доступ к базе данных или сети. | Переместите все блокирующие операции ввода-вывода из основного потока. |
Конфликт блокировки | Основной поток заблокирован в ожидании получения блокировки. | Уменьшите конфликты блокировок между основным потоком и другим потоком. Оптимизируйте медленный код в другом потоке. |
Дорогая рама | Рендеринг слишком большого количества данных в одном кадре, что приводит к серьезным зависаниям. | Меньше работайте над разрывом рамы. Не используйте алгоритмы n 2 . Используйте эффективные компоненты для таких задач, как прокрутка или пейджинг, например библиотеку Jetpack Paging . |
Заблокировано другим компонентом | Другой компонент, например приемник широковещательных сообщений, работает и блокирует основной поток. | Максимально переместите работу, не связанную с пользовательским интерфейсом, из основного потока. Запускайте приемники вещания в другом потоке. |
Графический процессор зависает | Зависание графического процессора — это системная или аппаратная проблема, которая приводит к блокировке рендеринга и, следовательно, к ошибке ANR при отправке ввода. | К сожалению, обычно никаких исправлений со стороны приложения не бывает. Если возможно, обратитесь к специалистам по оборудованию для устранения неполадок. |
Как отладить
Начните отладку, просмотрев сигнатуру кластера ANR в консоли Google Play или Firebase Crashlytics . Кластер обычно содержит верхние кадры, предположительно вызывающие ошибку ANR.
На следующей блок-схеме показано, как определить причину отправки ANR по тайм-ауту ввода.
![](https://developer.android.google.cn/static/topic/performance/images/debug-input-dispatch-anr.png?authuser=3&hl=ru)
Play Vitals может обнаружить и помочь устранить некоторые из этих распространенных причин ANR. Например, если Vitals обнаружит, что ошибка ANR произошла из-за конфликта блокировок, она может суммировать проблему и рекомендовать ее исправление в разделе ANR Insights .
![](https://developer.android.google.cn/static/topic/performance/images/play-vitals-anr-detection.png?authuser=3&hl=ru)
Нет сфокусированного окна
В то время как такие события, как прикосновение, отправляются непосредственно в соответствующее окно на основе тестирования нажатия, для таких событий, как клавиши, требуется цель. Эта цель называется сфокусированным окном . На каждом дисплее имеется только одно сфокусированное окно, и обычно это окно, с которым в данный момент взаимодействует пользователь. Если сфокусированное окно не может быть найдено, ввод вызывает ANR без сфокусированного окна . ANR без сфокусированного окна — это тип ANR отправки ввода.
Период ожидания по умолчанию : 5 секунд.
Распространенные причины
Ошибки ANR без сфокусированного окна обычно вызваны одной из следующих проблем:
- Приложение выполняет слишком много работы и слишком медленно рисует первый кадр.
- Главное окно не фокусируется. Если окно помечено флагом
FLAG_NOT_FOCUSABLE
, пользователь не сможет отправлять ему события клавиш или кнопок.
Котлин
override fun onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) window.addFlags(WindowManager.LayoutParams.FLAG_FLAG_NOT_FOCUSABLE) }
Ява
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); }
Таймаут широковещательного приемника
Ошибка ANR широковещательного приемника возникает, когда широковещательный приемник не обрабатывает трансляцию вовремя. Для синхронных получателей или получателей, которые не вызывают goAsync()
, тайм-аут означает, что onReceive()
не завершился вовремя. Для асинхронных получателей или получателей, вызывающих goAsync()
, тайм-аут означает, что PendingResult.finish()
не был вызван вовремя.
Ошибки ANR широковещательного приемника часто возникают в следующих потоках:
- Основной поток, если проблема связана с медленным запуском приложения.
- Поток запуска широковещательного приемника, если проблема связана с медленным кодом
onReceive()
. - Широковещательные рабочие потоки, если проблема связана с медленной трансляцией кода
goAsync()
.
Чтобы избежать ошибок ANR широковещательного приемника, следуйте следующим рекомендациям:
- Убедитесь, что приложение запускается быстро, поскольку оно учитывается в тайм-ауте ANR, если приложение запускается для обработки широковещательной рассылки.
- Если используется
goAsync()
, убедитесь,PendingResult.finish()
вызывается быстро. На это распространяется тот же тайм-аут ANR, что и на приемники синхронного вещания. - Если используется
goAsync()
, убедитесь, что рабочие потоки не используются совместно с другими длительными или блокирующими операциями. - Рассмотрите возможность использования
registerReceiver()
для запуска приемников широковещательных сообщений в неосновном потоке, чтобы избежать блокировки кода пользовательского интерфейса, выполняемого в основном потоке.
Периоды тайм-аута
Периоды ожидания приема широковещательной рассылки зависят от того, установлен ли флаг намерения переднего плана, и от версии платформы.
Тип намерения | Android 13 и более ранние версии | Андроид 14 и выше |
---|---|---|
Приоритетное намерение на переднем плане (установлен | 10 секунд | 10-20 секунд, в зависимости от того, испытывает ли процесс нехватку процессора |
Фоновое приоритетное намерение ( | 60 секунд | 60–120 секунд, в зависимости от того, загружен ли процесс процессором |
Чтобы определить, установлен ли флаг FLAG_RECEIVER_FOREGROUND
, найдите «flg=" в теме ANR и проверьте наличие 0x10000000
. Если этот бит установлен, то для намерения установлен FLAG_RECEIVER_FOREGROUND
и, следовательно, время ожидания короче.
Пример объекта ANR с коротким тайм-аутом трансляции (10–20 секунд):
Broadcast of Intent { act=android.inent.action.SCREEN_ON flg=0x50200010 }
Пример объекта ANR с длительным тайм-аутом трансляции (60–120 секунд):
Broadcast of Intent { act=android.intent.action.TIME_SET flg=0x25200010 }
Как измеряется время трансляции
Измерение продолжительности трансляции начинается, когда трансляция отправляется с system_server
в приложение, и заканчивается, когда приложение завершает обработку трансляции. Если процесс приложения еще не запущен, ему также необходимо выполнить холодный запуск в течение периода ожидания ANR. Следовательно, медленный запуск приложения может привести к ошибкам ANR широковещательного приемника.
На следующем рисунке показана временная шкала ANR широковещательного приемника, согласованная с определенными процессами приложения.
![](https://developer.android.google.cn/static/topic/performance/images/broadcast-receiver-anr-timeline.png?authuser=3&hl=ru)
Измерение тайм-аута ANR заканчивается, когда получатель завершает обработку трансляции: когда именно это произойдет, зависит от того, синхронный это приемник или асинхронный.
- Для синхронных приемников измерение прекращается, когда
onReceive()
возвращает значение. - Для асинхронных приемников измерение прекращается при вызове
PendingResult.finish()
.
![](https://developer.android.google.cn/static/topic/performance/images/sync-async-measurement-end.png?authuser=3&hl=ru)
Распространенные причины
Ниже приведены некоторые распространенные причины и предлагаемые исправления ошибок ANR широковещательного приемника.
Причина | Применяется к | Что случилось | Предлагаемое исправление |
---|---|---|---|
Медленный запуск приложения | Все ресиверы | Приложению потребовалось слишком много времени для холодного запуска. | Оптимизируйте медленный запуск приложения. |
onReceive() не запланировано | Все ресиверы | Поток приемника широковещательной рассылки был занят другой работой и не смог запустить метод onReceive() . | Не выполняйте длительные задачи в потоке-получателе (и не перемещайте получателя в выделенный поток). |
Медленно onReceive() | Все приемники, но в основном синхронные | Метод onReceive() был запущен, но был заблокирован или работал медленно, поэтому не завершился вовремя. | Оптимизируйте медленный код получателя. |
Задачи асинхронного приемника не запланированы | приемники goAsync() | Метод onReceive() пытался выполнить работу над заблокированным пулом рабочих потоков, поэтому работа так и не началась. | Оптимизируйте медленные или блокирующие вызовы или используйте разные потоки для широковещательных исполнителей и других долго выполняющихся задач. |
Рабочие работают медленно или заблокированы | приемники goAsync() | При обработке широковещательной рассылки где-то в пуле рабочих потоков произошла блокировка или медленная операция. Итак, PendingResult.finish не был вызван вовремя. | Оптимизируйте медленный async код приемника. |
Забыл вызвать PendingResult.finish | приемники goAsync() | Вызов finish() отсутствует в пути к коду. | Убедитесь, что finish() всегда вызывается. |
Как отладить
На основе подписи кластера и отчета ANR вы можете найти поток, в котором работает получатель, а затем конкретный код, который отсутствует или работает медленно.
На следующей блок-схеме показано, как определить причину ошибки ANR широковещательного приемника.
![](https://developer.android.google.cn/static/topic/performance/images/debug-broadcast-receiver-timeout-anr.png?authuser=3&hl=ru)
Найдите код получателя
Консоль Google Play показывает класс получателя и намерение трансляции в подписи ANR. Ищите следующее:
-
cmp=<receiver class>
-
act=<broadcast_intent>
Вот пример подписи ANR широковещательного приемника:
com.example.app.MyClass.myMethod
Broadcast of Intent { act=android.accounts.LOGIN_ACCOUNTS_CHANGED
cmp=com.example.app/com.example.app.MyAccountReceiver }
Найдите поток, в котором выполняется метод onReceive().
Если вы используете Context.registerReceiver
для указания пользовательского обработчика, это поток, запускающий этот обработчик. В противном случае это основной поток.
Пример: задачи асинхронного приемника не запланированы
В этом разделе рассматривается пример отладки ANR широковещательного приемника.
Скажем, подпись ANR выглядит следующим образом:
com.example.app.MyClass.myMethod
Broadcast of Intent {
act=android.accounts.LOG_ACCOUNTS_CHANGED cmp=com.example.app/com.example.app.MyReceiver }
Судя по подписи, цель трансляции — android.accounts.LOG_ACCOUNTS_CHANGED
, а класс получателя — com.example.app.MyReceiver
.
Из кода приемника можно определить, что основную работу по обработке этой трансляции выполняет пул потоков «BG Thread[0,1,2,3]». Глядя на дампы стека, вы можете видеть, что все четыре фоновых (BG) потока имеют один и тот же шаблон: они запускают блокирующий вызов getDataSync
. Поскольку все потоки BG были заняты, трансляцию не удалось обработать вовремя, что привело к ошибке ANR.
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.google.cn/static/topic/performance/images/debug-execute-service-anr.png?authuser=3&hl=ru)
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)
Если вы не видите вызовы важных функций, есть еще пара возможностей:
- Служба запущена или завершает работу, а это значит, что стеки принимаются слишком поздно. В этом случае вы можете игнорировать ANR как ложное срабатывание.
- Запущен другой компонент приложения, например приемник широковещательных сообщений. В этом случае основной поток, вероятно, заблокирован в этом компоненте, что препятствует запуску службы.
Если вы видите вызов ключевой функции и можете определить, где обычно происходит ошибка ANR, проверьте остальные стеки основных потоков, чтобы найти медленную операцию и оптимизировать ее или убрать с критического пути.
Более подробную информацию об услугах можно найти на следующих страницах:
Поставщик контента не отвечает
Ошибка ANR поставщика контента возникает, когда удаленному поставщику контента требуется больше времени, чем период ожидания, чтобы ответить на запрос, и он отключается.
Период ожидания по умолчанию : указывается поставщиком контента с помощью ContentProviderClient.setDetectNotResponding
. Период ожидания ANR включает общее время выполнения запроса к удаленному поставщику контента, включая холодный запуск удаленного приложения, если оно еще не запущено.
Чтобы избежать ошибок ANR поставщика контента, следуйте следующим рекомендациям:
- Убедитесь, что приложение запускается быстро, поскольку оно учитывается в тайм-ауте ANR, если приложение запускается с запуском поставщика контента.
- Убедитесь, что запросы к поставщику контента выполняются быстро.
- Не выполняйте множество одновременных вызовов блокирующего связывателя, которые могут заблокировать все потоки связывателя приложения.
Распространенные причины
В следующей таблице перечислены распространенные причины ошибок ANR поставщика контента и предлагаемые исправления.
Причина | Что происходит | Сигнал | Предлагаемое исправление |
---|---|---|---|
Медленный запрос к поставщику контента | Поставщик контента выполняется слишком долго или заблокирован. | Фрейм android.content.ContentProvider$Transport.query находится в потоке связывания. | Оптимизируйте запрос поставщика контента. Узнайте, что блокирует нить переплета. |
Медленный запуск приложения | Приложение поставщика контента запускается слишком долго. | Кадр ActivityThread.handleBindApplication находится в основном потоке. | Оптимизируйте запуск приложения. |
Исчерпан поток связующего — все потоки связующего заняты. | Все потоки связывания заняты обслуживанием других синхронных запросов, поэтому вызов связывателя поставщика контента не может быть выполнен. | Приложение не запускается, все потоки подшивки заняты, а поставщик контента не работает. | Уменьшите нагрузку на связующие нити. То есть делайте меньше синхронных исходящих вызовов связывателя или выполняйте меньше работы при обработке входящих вызовов. |
Как отладить
Чтобы отладить ANR поставщика контента с помощью сигнатуры кластера и отчета ANR в консоли Google Play или Firebase Crashlytics, посмотрите, что делают основной поток и потоки связывания.
Следующая блок-схема описывает, как отладить ANR поставщика контента:
![](https://developer.android.google.cn/static/topic/performance/images/debug-content-provider-anr.png?authuser=3&hl=ru)
В следующем фрагменте кода показано, как выглядит поток подшивки, когда он заблокирован из-за медленного запроса поставщика контента. В этом случае запрос поставщика контента ожидает блокировки при открытии базы данных.
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)
В следующем фрагменте кода показано, как выглядит основной поток, когда он заблокирован из-за медленного запуска приложения. В этом случае запуск приложения происходит медленно из-за конфликта блокировок во время инициализации кинжала.
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)
Медленный ответ на задание
Медленный ответ на задание ANR происходит, когда приложению требуется слишком много времени, чтобы ответить на JobService.onStartJob()
или JobService.onStopJob()
, или слишком долго требуется для предоставления уведомления с помощью JobService.setNotification()
. Это говорит о том, что основной поток приложения заблокирован, делая что-то другое.
Если это проблема с JobService.onStartJob()
или JobService.onStopJob()
, проверьте, что происходит в основном потоке. Если проблема связана с JobService.setNotification()
, обязательно вызовите ее как можно быстрее. Не делайте много работы перед отправкой уведомления.
Загадочные ошибки ANR
Иногда неясно, почему возникает ошибка ANR, или в сигнатуре кластера и отчете ANR недостаточно информации для ее отладки. В этих случаях вы все равно можете предпринять некоторые шаги, чтобы определить, является ли ANR действенным.
Очередь сообщений простаивает или NativePollOnce
Если вы видите фрейм android.os.MessageQueue.nativePollOnce
в стеках, это часто указывает на то, что предположительно не отвечающий поток на самом деле простаивал и ждал сообщений петлителя. В консоли Google Play сведения об ANR выглядят следующим образом:
Native method - android.os.MessageQueue.nativePollOnce
Executing service com.example.app/com.example.app.MyService
Например, если основной поток простаивает, стеки выглядят так:
"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)
Существует несколько причин, по которым предположительно не отвечающий поток может простаивать:
- Поздний дамп стека . Поток восстановился в течение короткого периода между срабатыванием ANR и сбросом стека. Задержка в Pixels на Android 13 составляет около 100 мс, но может превышать 1 с. Задержка в Pixels на Android 14 обычно составляет менее 10 мс.
- Неправильная атрибуция темы . Поток, использованный для создания подписи ANR, не был фактически неотвечающим потоком, вызвавшим ANR. В этом случае попытайтесь определить, относится ли ANR к одному из следующих типов:
- Общесистемная проблема . Процесс не был запланирован из-за большой нагрузки на систему или проблемы на системном сервере.
Нет кадров стека
Некоторые отчеты ANR не включают стеки с ANR, что означает, что при создании отчета ANR произошел сбой дампа стека. Существует несколько возможных причин отсутствия кадров стека:
- Взятие стека занимает слишком много времени и времени истекает.
- Процесс умер или был завершен до того, как стеки были взяты.
[...]
--- 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 без кадров стека недействительны из сигнатуры кластера или отчета ANR. Для отладки просмотрите другие кластеры приложения, поскольку, если проблема достаточно велика, у него обычно будет собственный кластер, в котором присутствуют кадры стека. Другой вариант — посмотреть следы Perfetto .
Известные проблемы
Сохранение таймера в процессе вашего приложения с целью завершения обработки широковещательной рассылки до срабатывания триггера ANR может работать неправильно из-за асинхронного способа мониторинга ошибок ANR.