Все anr android что это

Приложение отвечает: как мы уменьшили количество ANR-ошибок в шесть раз. Часть 1, про сбор данных

Пожалуй, одна из худших проблем, которая может случиться с вашим приложением, — ошибка ANR (Application Not Responding), когда приложение не отвечает. Если таких ошибок много, они могут негативно влиять не только на пользовательский опыт, но и на позицию в выдаче Google Play и фичеринг.

В начале прошлого года количество ANRs в приложении Badoo превышало порог “Bad Behaviour” в Google Play. Поэтому мы собрали команду для решения этой проблемы и потратили несколько месяцев, экспериментируя с разными подходами. В результате мы смогли уменьшить количество таких ошибок более чем в шесть раз.

В этой серии из двух статей я расскажу о том, как нам это удалось, что дало наибольший эффект и как вы можете использовать эти подходы в своём приложении.

В первой части мы поговорим об основах: что представляет собой ошибка ANR и как её лучше отслеживать. Если вы уже знакомы с этой темой, предлагаю перейти ко второй части, в которой я расскажу о наших способах решения этой проблемы.

Что такое ошибка ANR?

Обычно любое приложение с графическим интерфейсом выполняет все связанные с ним операции и отрисовку в отдельном UI-потоке исполнения. Android не исключение: здесь в главном потоке приложения выполняется цикл, отвечающий за все действия с интерфейсом:

При использовании этого цикла крайне важно не выполнять длительные операции, потому что это напрямую повлияет на отзывчивость приложения. Если в главном потоке выполнять слишком много действий, это может привести к снижению частоты кадров или даже к зависаниям интерфейса:

Чтобы как-то идентифицировать такие ситуации, в Android ввели понятие ANR, с помощью которого система сообщает, что приложение зависло. Вот что об этом говорится в официальной документации:

Когда UI-поток Android-приложения блокируется слишком долго, выдаётся ошибка Application Not Responding (ANR).

ANR выдаётся, когда приложение находится в одном из этих состояний:

— на переднем плане находится Activity, приложение в течение пяти секунд не отвечает на входящие события или BroadcastReceiver, например нажатия на кнопки или касания экрана;

— на переднем плане нет Activity, ваш BroadcastReceiver не закончил исполнение в течение длительного времени.

Если ANR случается, когда на переднем плане находится Activity вашего приложения, Android показывает диалоговое окно с предложением закрыть приложение или подождать.

Довольно легко принудительно вызвать ANR, написав Thread.sleep() в любом обработчике интерфейса, например обработчик нажатия кнопки. После нажатия на кнопку вы увидите примерно следующее:

Наличие ошибок ANR в вашем приложении не только влияет на опыт его использования, но и, согласно документации Google, может повлиять на позицию в поисковой выдаче и продвижение в Google Play.

Чтобы снизить вероятность возникновения ANR, нужно всего лишь избегать выполнения длительных операций в главном потоке. Звучит вроде бы просто, но иногда не так легко определить корневую проблему, которая приводит к таким ошибкам. Поэтому довольно важно иметь хорошую систему мониторинга и репортинга ANR-ошибок.

Давайте посмотрим, какие существуют способы отладки ANR-ошибок и какие инструменты могут быть в этом полезны.

Отслеживание ANR

Локальный анализ

Самый простой случай — если у вас есть возможность стабильно воспроизводить ANR-проблему локально. Существует довольно много инструментов, которые могут помочь вам быстро найти источник проблемы.

Первое, что можно сделать, — это проверить дамп стек-трейсов для всех потоков (thread dump). Когда приложение перестает отвечать, Android создаёт дамп всех текущих потоков, который может помочь в анализе проблемы. Обычно он находится в директории /data/anr/, точный путь можно найти в Logcat сразу после сообщения об ошибке ANR.

Дамп потоков содержит стек-трейсы: вы увидите, в каком состоянии был каждый поток (например, какая строка выполнялась в конкретный момент времени). По сути, это состояние приложения на момент создания дампа.

Чаще всего причина возникновения ANR обнаруживается в стек-трейсе главного потока скорее всего, код в этом месте выполняется слишком долго. Если информации из этого стек-трейса будет недостаточно, можно попробовать обратиться к довольно неплохой документации от Google, где описываются основные причины, способы диагностирования и решения проблемы ANR.

Отслеживание с помощью Google Play

Google Play автоматически отправляет отчёты об ошибках ANR, если у пользователя включена такая опция. В консоли Google Play есть несколько метрик и инструментов для анализа ANR.

Во-первых, можно увидеть агрегированные графики с общим количеством ANR-ошибок за день. Также есть такая метрика, как ANR rate — отношение количества сессий за день, в которых возникала хотя бы одна ANR-ошибка, к общему количеству сессий за сутки. Для этой метрики задан порог в 0,47%, превышение которого считается «неудовлетворительным поведением» (“Bad Behaviour”) и может плохо повлиять на позицию приложения в Google Play.

Читайте также:  Getting current activity android

Во-вторых, можно открывать отдельные отчёты об ANR-ошибках, сгруппированные по схожести на основе стек-трейса. Основные группы находятся в разделе Android Vitals. И это, вероятно, наиболее полезный раздел для выявления самых частых причин возникновения ANR-ошибок в вашем приложении.

Если вы активно используете консоль Google Play, вы могли заметить некоторые её недостатки. Например, к отчётам нельзя прикрепить дополнительную информацию, такую как логи для отладки. Также невозможно настроить логику группировки отчётов. Иногда система помещает в одну группу ошибки, возникшие по разным причинам, а иногда раскидывает по разным группам ошибки, у которых причина одна.

Всё это иногда затрудняет определение основных ошибок и поиск изначальных проблем. Что же можно сделать для улучшения ситуации?

Скачивание данных из Google Play

Для решения проблемы с логикой группировки можно попробовать скачать сырые отчёты об ANR-ошибках из Google Play для последующего ручного анализа. Раньше была возможность выгрузить эти данные из Google Cloud Storage, но несколько лет назад Google перестала поддерживать этот функционал:

Однако всё ещё можно просматривать отдельные отчёты в консоли. Но как нам экспортировать тысячи отчётов, не потратив при этом кучу времени на рутинную работу?

Существует много способов автоматизировать сбор информации с сайтов. Самый правильный и простой — получение данных через API, но, к сожалению, Google не предоставляет публичный API для получения отчётов. Одно из решений — эмулировать пользовательское поведение, автоматически кликая на ссылки и кнопки в браузере и сохраняя отображающийся текст.

Веб-скрапер можно реализовать с помощью популярного инструмента Selenium, который предоставляет простой интерфейс для взаимодействия с веб-страницами. Изначально он предназначался для создания автоматизированных тестов для веб-приложений и доступен на разных языках, включая Java и Kotlin.

Мы реализовали скрапер на Selenium и получили сырые отчёты об ANR-ошибках для одного из релизов. Благодаря этому нам удалось проанализировать их так, как не получилось бы сделать с помощью встроенных в консоль Google Play инструментов. Например, просто поискав в отчётах по ключевым словам “Application.onCreate”, мы обнаружили, что около 60% ошибок произошло во время выполнения метода Application.onCreate. При этом в консоли Google Play нет возможности получить такую информацию, так как отчёты разбиты по группам.

Внутренняя аналитика

Другой способ сбора дополнительных данных и проведения расширенного анализа заключается в настройке собственного репортинга ANR-ошибок. В прошлом мы уже экспериментировали с решением похожих проблем, настраивая репортинг крашей. Для того чтобы проводить анализ падений приложения, мы создали внутренний инструмент Gelato.

Его функциональность схожа с возможностями других инструментов для краш-репортинга, таких как Firebase Crashlytics и App Center, но ещё и позволяет нам полностью контролировать сохраняемые данные, менять логику группировки и применять сложную фильтрацию:

Это не реальные данные приложения Bumble, иллюстрация сделана просто для примера

Мы решили отслеживать в Gelato ещё и ANR-ошибки в надежде, что это поможет нам в поиске их причин. Для этого нам нужно было знать, когда приложение перестаёт отвечать. В Android 11 появился новый API, предоставляющий информацию о недавних причинах завершения процесса, но у большинства наших пользователей установлены более ранние версии ОС, поэтому нам требовалось найти другое решение.

И мы нашли простой способ, который часто используется для отслеживания зависаний главного потока исполнения: запустить watchdog-поток, который периодически будет пытаться выполнить задачу в главном потоке. Если задача не выполняется за определённый промежуток времени, то можно сохранить дамп текущего состояния потоков и отправить его в наш инструмент для анализа отчётов о падениях:

Такую логику реализует, например, библиотека, которой мы воспользовались для реализации репортинга в Gelato. Это позволило нам проводить более глубокий анализ данных и лучше интегрировать этот инструмент в нашу инфраструктуру. Например, теперь мы можем сравнивать зависания главного потока в разных вариантах в ходе A/B-тестирования.

Вот пример отчёта в нашей системе:

Это не реальные данные приложения Bumble, иллюстрация сделана просто для примера

Полезный совет: собирайте и отправляйте вместе с отчётом лог событий аналитики. Иногда это даёт возможность буквально пошагово воспроизвести проблему.

Если у вас нет своего решения для сбора отчётов о падениях приложения, вы можете настроить репортинг и в сторонние инструменты. Например, можно отправлять ANR-ошибки в App Center или Firebase Crashlytics, так как они предоставляют API для отправки кастомных крашей.

Но помните, что все эти отчёты нельзя считать полной альтернативой ANR-отчётам в Google Play (как мы говорили выше, в Android немного другие правила определения таких ошибок). Но в любом случае это может помочь получить общее представление об основных проблемах. Вполне вероятно, что если генерируется много отчётов о зависании главного потока исполнения в какой-то части вашего приложения, то в ней происходят и ANR-ошибки.

Читайте также:  Инструкция по сборке андроид

В завершение

Мы обсудили, что представляют собой ANR-ошибки и как их можно отслеживать. Во второй части статьи я расскажу о наших подходах к снижению ANR rate и о том, что из этого получилось.

Источник

Русские Блоги

Подробный анализ Android ANR

анализ файла трассировки

Краткое понимание ANR
Информация о стеке функций каждого процесса приложения и системного процесса выводится в файл /data/anr/traces.txt,

Причина использования каталога pull заключается в том, что некоторые мобильные телефоны будут выводить файлы эксклюзивных трассировок для различных приложений, поэтому в каталоге / data / anr будет множество файлов трассировок. Как правило, сторонняя разработка приложений заботится только о своих собственных приложениях и не имеет привилегий root. Следовательно, только файл трассировок может быть проанализирован для определения местоположения anr, и три общие проблемы ANR могут быть решены в соответствии с модулем и страницей, которые воспроизводит проблема, в сочетании с файлом трассировок. Откройте файл трассировки и найдите свое собственное имя пакета приложения, чтобы найти классы и методы, которые вызывают anr в передней и задней позициях. следующим образом:

1. Основной поток заблокирован, и в течение 5 секунд нет ответа на входные события, такие как события onClick. Это основной тип проблем ANR. Обычно разработчики не допускают таких ошибок. Все трудоемкие операции будут обрабатываться отдельными потоками. Если вы не посмотрите на свой собственный код, вы будете знать, как с ним бороться.

  1. BroadcastReceiver запускается в главном потоке программы, и по умолчанию время выполнения BroadcastReceiver составляет 10 с, поэтому не может быть никаких трудоемких операций.Если это занимает более 10 с, это вызовет anr. Из журнала файла трассировки видно, что onReceive не может выполнять трудоемкие задачи. ,

3. Сервис является вычислительным компонентом. Хотя он работает в фоновом режиме, он, по сути, работает в основном потоке. Если ваша служба выполняет какие-либо ресурсоемкие (например, воспроизведение MP3) или блокирующие (например, сетевые) операции, она должна быть размещена В дочернем потоке, в противном случае требуется более 20 секунд, чтобы вызвать anr. Обратите внимание, что метод anr — это метод, который я написал сам. В методе onStartCommand () есть трудоемкие задачи, просто поместите его в дочерний поток, например: поместите следующий метод anr () в дочерний поток

Анализ информации файла трассировки

// В начале отображаются номер процесса, момент времени появления ANR и имя процесса

Как избежать ANR при разработке сторонних приложений

Три распространенные ситуации при разработке сторонних приложений были подробно представлены в предыдущей статье. Идея избежать anr ясна. Краткое резюме:

  1. Никогда не выполняйте сложные и трудоемкие операции с основным потоком, такие как отправка и получение сетевых данных, выполнение большого количества вычислений, работа с базами данных, чтение и запись файлов и т. Д., Все используют асинхронные операции

2. Когда broadCastReceiver должен выполнять сложные операции, вы можете запустить IntentService или JobIntentService в методе onReceive (), чтобы сделать это.

  1. Лучше всего использовать асинхронные задачи для трудоемких операций в Сервисе.

4. Избегайте неподходящих ситуаций, таких как синхронизация / тупик, тупик и т. Д. На этапе разработки и написания кода

ANR в разработке системы Android

Для разработчиков системы недостаточно только файла /data/anr/traces.txt. Поскольку, несмотря на наличие anr, в файле трассировки нет журнала anr или в файле трассировки есть журнал, но причина проблемы anr не может быть найдена.
ANR оказывает относительно большое влияние на стабильность системы, и испытательный центр будет рассматривать ANR как важный случай для стабильности системы. Разработчики системы обычно используют инструменты и системные журналы для анализа. Anr сообщается в модуле, за который вы отвечаете, но причина anr, вероятно, кроется в других модулях, особенно при выполнении тестов стабильности. Трудно исследовать отдельные проблемы ANR. В конце концов, сценарии все еще несколько отличаются от ручных операций, и такие проблемы, как фрагментация памяти, сбои оборудования и т. Д., Невозможно исследовать на базовом прикладном уровне. По крайней мере, это трудно выяснить отдельным людям. Это может потребовать внимания команды (например, ядра, BSP) ), даже обратную связь с производителем решить.

Согласно моему опыту, следующие ситуации будут вызывать ANR:
  • Нагрузка на процессор, приводящая к тому, что основной поток не может выгрузить квант времени процессора, обращает внимание на процессы с высокой загрузкой процессора
  • Высокий уровень ввода-вывода, например, неправильный доступ к базе данных, приводит к ее перегрузке (центральный процессор использует iowait в журнале для учета высокой доли)
  • Недостаточно памяти (мало памяти), например, из-за недостатка памяти блок создает растровое изображение
  • Deadlock запускает ANR, и неосновной поток содержит объект блокировки, необходимый для основного потока, в результате чего основной поток ожидает тайм-аут. Обычно в журнале блокируются | -locked | ожидающие блокировки |, удерживаемые потоком. В настоящее время процессор в основном простаивает. Очень низкий процент использования
  • Текущий процесс приложения выполняет межпроцессное взаимодействие для запроса других процессов, и в течение длительного времени нет обратной связи по операциям других процессов, таких как операционная аппаратная камера.
  • Количество связующих сервисов достигает верхнего предела
  • Триггер WatchDog ANR в system_server
Читайте также:  Как обновить андроид через kies samsung

Конечно, проблема ANR в предыдущем приложении также появится. Разработка системы относительно сложна, и невозможно разобраться в общих случаях. Я могу говорить только о том, как анализировать после ANR.
Я лично много работаю на платформе MTK. Платформа имеет свои собственные инструменты и документы. В принципе, вы можете выполнять эту работу, если вы посмотрите на документ и изучите его.

Используйте инструмент GAT

GAT — это инструмент, который интегрирует множество функций отладки во вторичную разработку и упаковку MTK на основе DDMS.В дополнение к исходным функциям DDMS, он также поддерживает захват ядра, получает список собственных процессов, декодирование с возвратом и извлекает отладку на мобильном телефоне. Информационные и другие функции. Когда MTKLogger ненормальный, часто необходимо использовать инструмент GAT для захвата журнала.

В mtklog есть файл aee_exp, в нем два файла, один ZZ_INTERNAL, и есть только одно предложение, в котором говорится о том, какая ошибка была сообщена, номер процесса, в котором произошла ошибка, программа, в которой произошла ошибка, и время ошибки.

Другой файл называется db.01.JE. Этот файл содержит конкретную информацию о сообщении об ошибке и о хранении различных состояний машины, когда сообщается об ошибке, но этот файл можно открыть только с помощью программного обеспечения gat, специально созданного mtk.

Нажмите в окне — openlogView в меню, выберите file-OpenAeeDB, выберите файл в формате dbg, который нужно открыть, список слева — это информация о различных ошибках, наиболее важным является первый элемент exp_main.txt, находящийся в том же каталоге. Все файлы будут выведены.

Нажмите на него, чтобы найти самое важное сообщение об ошибке, описание информации очень прямое, и соответствующая программа может понять эту информацию

Загрузка процессора в течение периода времени до и после появления ANR

Коэффициент использования ЦП можно понимать как отношение времени без учета времени простоя ЦП (обозначается как I) в течение периода времени (обозначенного как T) к этому периоду времени T, которое можно выразить в виде формулы:
Загрузка процессора = (T — I) / T
А период времени T — это разница во времени между двумя моментами выборки. Причиной такого расчета является то, что ядро ​​Linux будет записывать всю информацию о времени от запуска системы до текущего времени активности процессора. Мы можем получить эту информацию, просмотрев файл «/ proc / stat». Это в основном включает в себя следующие времена, которые рассчитываются от запуска системы, и единица измерения составляет 0,01 секунды:
user: время работы процессора в режиме пользователя, исключая время работы процессов с отрицательным значением nice
nice: время выполнения процесса, процессор которого находится в режиме пользователя, а значение nice отрицательно
Система : время работы процессора в режиме ядра
idle: время простоя процессора, не включая время iowait
iowait: время, в течение которого процессор ожидает операции ввода-вывода
irq: время жесткого прерывания процессора
softirq: время мягкого прерывания процессора

Часть «faults: xxx minor / major» в последнем выводе данных об использовании ЦП процесса указывает на количество сбоев страниц и не отображается, если число равно 0. Major относится к Major Page Fault (MPF для краткости) .При чтении данных ядро ​​просматривает кэш ЦП и физическую память один за другим, а если не может найти его, отправляет MPF-сообщение с просьбой загрузить данные в память. Незначительный относится к незначительной ошибке страницы (Minor Page Fault, MnPF для краткости). После того, как данные диска загружены в память, когда ядро ​​прочитает их снова, сообщение MnPF будет отправлено. Когда файл будет прочитан и записан в первый раз, будет много MPF. После кэширования в памяти будет снова мало обращений к MPF, и вместо этого увеличится MnPF. Это технология кэширования, принятая ядром для уменьшения неэффективных операций ввода-вывода на диске. результат.

Если вы обнаружите, что iowait обеспечивает высокий процент использования ЦП при возникновении ANR, вы можете определить, какой процесс выполняет операции дискового ввода-вывода, посмотрев на большинство процессов.

Как анализировать ЛОГ

Сначала понять основной файл журнала

Многие журналы не перечислены, но это наиболее часто используемые. Посмотрите на основные файлы журнала. Во-первых, найдите номер процесса приложения и имя процесса ANR в файлах ZZ_INTERNAL, __exp_main.txt, фильтр am_anr в журнале событий, записанном в SYS_ANDROID_EVENT_LOG, и соответствуют номеру процесса. Этот журнал событий в основном указывает, какой класс или операция в настоящее время находятся в. Вы можете посмотреть на свой собственный код

SWT_JBT_TRACES также находит соответствующий номер процесса, чтобы проверить, не достаточно ли кучи, а поток заблокирован. Как правило, потоки блокируются, а загрузка процессора обычно низкая.

Распределение и использование связующего, отчет о диагностическом анализе

Источник

Оцените статью