Если поток UI приложения Android заблокирован слишком долго, возникает ошибка "Приложение не отвечает" (ANR). Android Vitals отслеживает показатели ANR и создает отчеты о них в Google Play Console, чтобы вы могли следить за стабильностью и скоростью работы приложения на разных устройствах.
Показатели и пороговые значения Android Vitals
Android Vitals помогает отслеживать и снижать долю ошибок ANR в приложении. В Android Vitals отслеживается несколько показателей доли ошибок ANR:
- Доля ошибок ANR. Процент активных пользователей за день, столкнувшихся с ошибкой ANR любого типа.
- Доля ошибок ANR в активном режиме. Процент активных пользователей за день, столкнувшихся по крайней мере с одной ошибкой ANR в активном режиме. Сейчас к ошибкам ANR в активном режиме относятся только ошибки типа
Input dispatching timed out. - Доля повторных ошибок ANR. Процент активных пользователей за день, столкнувшихся по крайней мере с двумя ошибками ANR.
Активный пользователь за день – это уникальный пользователь, который запускает ваше приложение на одном устройстве в течение одного дня. При этом он может совершить несколько сеансов. Если пользователь в течение одного дня запускает приложение на нескольких устройствах, каждое из них учитывается при расчете количества активных пользователей за этот день.
Доля ошибок ANR в активном режиме – один из основных показателей Android Vitals. Он влияет на параметры видимости приложения в Google Play. Этот показатель важен, так как учитывающиеся в нем ошибки возникают во время работы с приложением и доставляют неудобства пользователям.
В Google Play определены два порога соответствия для этого показателя:
- Порог соответствия (в целом). Как минимум 0, 47% активных пользователей за день сталкиваются с ошибками ANR в активном режиме на любых моделях устройств.
- Порог соответствия (по модели устройства). Как минимум 8% активных пользователей за день сталкиваются с ошибками ANR в активном режиме на определенной модели устройства.
Если приложение превышает общий порог соответствия, оно, скорее всего, будет реже показываться на всех устройствах. Если порог соответствия превышен на некоторых устройствах, вероятно, приложение будет реже показываться в Google Play на них. На странице приложения также может появиться сообщение с предупреждением.
Android Vitals может оповещать вас в Play Console, когда в вашем приложении часто возникают ошибки ANR.
Информацию о том, как Google Play собирает данные Android Vitals, можно найти в документации Play Console.
Обнаружение проблемы
Если приложение находится в активном режиме, когда возникает ошибка ANR, система показывает пользователю диалоговое окно, как на рисунке 1. В диалоговом окне ANR пользователю предлагается принудительно закрыть приложение.
Ошибки ANR возникают, когда основной поток приложения, отвечающий за обновление интерфейса, не может обработать действия пользователя или отрисовать экран. Это мешает работе с приложением. Подробнее об основном потоке приложения…
Ошибка ANR возникает в следующих случаях:
- Время ожидания ввода истекло. Приложение не ответило на событие ввода (например, нажатие клавиши или касание экрана) в течение пяти секунд.
- Выполнение сервиса. Если сервис, объявленный в приложении, не может завершить выполнение
Service.onCreateиService.onStartCommandилиService.onBindв течение нескольких секунд. - Метод
Service.startForegroundне вызывается. Приложение используетContext.startForegroundService, чтобы запустить новую активную службу, но она не вызывает методstartForegroundв течение пяти секунд. - Трансляция намерения. Если
BroadcastReceiverне завершает выполнение в течение заданного времени. Если в приложении есть действия на переднем плане, время ожидания составляет 10 секунд. - Взаимодействия с
JobScheduler. ЕслиJobServiceне возвращается изJobService.onStartJobилиJobService.onStopJobв течение нескольких секунд или если запускается задача, инициированная пользователем, и ваше приложение не вызываетJobService.setNotificationв течение нескольких секунд после вызоваJobService.onStartJob. В приложениях, предназначенных для Android 13 и более ранних версий, ошибки ANR неявные и не регистрируются. В приложениях, предназначенных для Android 14 и более поздних версий, ошибки ANR явные и регистрируются.
Помимо Android Vitals, вы можете использовать другие инструменты для обнаружения ошибок ANR, однако сторонние инструменты не могут сообщать об ошибках ANR в Android 10 (уровень API 29) и более ранних версиях.
Диагностика ошибок ANR
При диагностике ошибок ANR следует обращать внимание на следующие распространенные проблемы:
- В основном потоке выполняются медленные операции ввода-вывода.
- Приложение выполняет длительные вычисления в основном потоке.
- Основной поток выполняет синхронный вызов механизма Binder к другому процессу, и этот процесс долго не возвращает результат.
- Основной поток заблокирован и ожидает синхронизированный блок для длительной операции, которая выполняется в другом потоке.
- Основной поток находится во взаимной блокировке с другим потоком в вашем процессе или через вызов Binder. Основной поток не просто ожидает завершения длительной операции, а находится в состоянии взаимной блокировки.
Определить причину ошибок ANR можно с помощью описанных ниже методов.
HealthStats
HealthStats предоставляет показатели работоспособности приложения, собирая данные об общем времени пользователя и системы, процессорном времени, сети, статистике радио, времени включения и выключения экрана и будильниках. Это поможет вам оценить общую загрузку процессора и расход заряда батареи.
Отладка
Debug помогает проверять приложения для Android во время разработки, в том числе отслеживать и подсчитывать распределение ресурсов, чтобы выявлять задержки и зависания.
Вы также можете использовать Debug, чтобы получить счетчики памяти среды выполнения и нативной памяти, а также показатели памяти, которые помогут вам определить объем потребляемой памяти определенного процесса.
ApplicationExitInfo
Метод ApplicationExitInfo доступен в Android 11 (уровень API 30) и более поздних версиях. Он позволяет получить информацию о причине закрытия приложения. К ним относятся ошибки ANR, нехватка памяти, сбои в работе приложения, чрезмерная загрузка ЦП, прерывания со стороны пользователя и системы, а также изменения динамических разрешений.
Строгий режим
StrictMode помогает находить случайные операции I/O в основном потоке во время разработки приложения. StrictMode можно использовать на уровне приложения или действия.
Включить диалоговые окна ANR в фоновом режиме
Android показывает диалоговые окна ANR для приложений, которые слишком долго обрабатывают широковещательное сообщение, только если в настройках для разработчиков на устройстве включен параметр Показывать все ошибки ANR. Поэтому диалоговые окна ошибок ANR в фоновом режиме не всегда показываются пользователю, даже если в приложении возникают проблемы производительности.
Профилирование ЦП и трассировка системы
Используйте Профилировщик ЦП в Android Studio, чтобы записывать трассировки системы и активность ЦП во время работы игры. Проверка основного потока Activity наряду с потоками рендеринга, аудио и рабочими потоками игрового движка помогает выявлять длинные кадры, синхронные загрузки объектов и конфликты потоков до того, как они вызовут ошибку ANR.
Как получить файл трассировки
При возникновении ошибки ANR Android сохраняет информацию о трассировке. В более ранних версиях Android на устройстве есть только один файл /data/anr/traces.txt. В более поздних версиях Android файлов /data/anr/anr_* несколько. Вы можете получить доступ к трассировкам ANR с устройства или эмулятора, используя Android Debug Bridge (adb) в качестве корневого каталога:
adb root
adb shell ls /data/anr
adb pull /data/anr/<filename>
Чтобы получить отчет об ошибке с физического устройства, используйте параметр "Отчет об ошибке" в разделе "Для разработчиков" на устройстве или команду adb bugreport на компьютере для разработки. Подробнее о том, как создавать и читать отчеты об ошибках…
Устраните проблемы
Определив проблему, вы можете воспользоваться советами из этого раздела, чтобы устранить распространенные неполадки.
Медленный код в основном потоке
Определите, в каких местах кода основной поток приложения занят более пяти секунд. Попробуйте воспроизвести ошибку ANR в подозрительных сценариях.
В играх остановки основного потока обычно происходят, когда синхронная декомпрессия ассетов, компиляция шейдеров или тяжелая инициализация состояния игры выполняются в основном потоке Activity Android (например, внутри обратных вызовов onCreate, onResume или JNI, вызываемых из потока UI). Перенесите выполнение игрового цикла, обработку объектов и инициализацию сцен в выделенные потоки движка, рендеринга или фоновые рабочие потоки, чтобы основной поток мог обрабатывать входные данные и события жизненного цикла.
Операция ввода-вывода в основном потоке
Выполнение операций ввода-вывода в основном потоке – распространенная причина медленной работы основного потока, которая может приводить к ошибкам ANR.
Перенесите все операции чтения наборов объектов, сериализацию сохранений, обращения к SharedPreferences и сетевые запросы из основного потока Activity в фоновые рабочие потоки. Это позволит избежать задержек при обработке ввода, связанных с хранилищем или сетью.
Взаимные блокировки
Взаимная блокировка происходит, когда поток переходит в режим ожидания, потому что необходимый ресурс занят другим потоком, который также ожидает ресурс, занятый первым потоком. Если в такой ситуации оказывается основной поток приложения, скорее всего, возникнет ошибка ANR.
В играх взаимные блокировки и конфликты блокировок часто возникают между основным потоком Activity Android (обрабатывающим обратные вызовы жизненного цикла, поверхности или ввода) и нативными потоками рендеринга, логики или аудио на C или C++. Избегайте синхронного ожидания в основном потоке блокировок нативного движка. Используйте согласованный порядок блокировок или очереди сообщений без блокировок при взаимодействии между потоками JNI и движка.
Взаимные блокировки – хорошо изученное явление в компьютерных науках, и существуют алгоритмы, которые позволяют их избежать.
Дополнительную информацию можно найти в статьях Википедии Взаимная блокировка и Алгоритмы предотвращения взаимной блокировки.
Медленные широковещательные приемники
Приложения могут реагировать на широковещательные сообщения, например о включении или отключении режима полета или об изменении статуса подключения, с помощью широковещательных приемников. Если приложение обрабатывает широковещательное сообщение слишком долго, возникает ошибка ANR.
Ошибка ANR возникает в следующих случаях:
- Широковещательный приемник не завершил выполнение метода
onReceiveв течение значительного времени. - Широковещательный приемник вызывает
goAsync, но не вызываетfinishдля объектаPendingResult.
В методе onReceive класса BroadcastReceiver должны выполняться только короткие операции. Однако если в результате оповещения приложению требуется выполнить более сложную обработку, то для задач, которые займут не более нескольких секунд, следует использовать фоновый рабочий поток, а для более длительных задач – WorkManager.
GameActivity
Библиотека GameActivity снижает количество ошибок ANR в играх и приложениях, написанных на C или C++. Это подтверждено исследованиями. Если вы замените существующий класс native activity на GameActivity, то сможете снизить количество блокировок потока UI и предотвратить некоторые ошибки ANR.
Если вы разрабатываете игру на Unity, прочитайте статьи Отладка ошибок ANR в играх на Unity, Распространенные ошибки ANR в играх на Unity и Добавление символов в отчеты о сбоях и ошибках ANR в играх на Unity.
Подробнее об ошибках ANR… Подробнее о повышении производительности за счет потоков…
Рекомендуем
- Примечание. Текст ссылки показывается, когда JavaScript отключен.
- Слишком частое пробуждение