- Приложение отвечает: как мы уменьшили количество ANR-ошибок в шесть раз. Часть 1, про сбор данных
- Что такое ошибка ANR?
- Отслеживание ANR
- Локальный анализ
- Отслеживание с помощью Google Play
- Скачивание данных из Google Play
- Внутренняя аналитика
- В завершение
- Все о функциях разработчика в вашем телефоне
- Константин Иванов
- «Разблокируем» функции разработчика в телефоне
- Настройки
Приложение отвечает: как мы уменьшили количество 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.
Во-вторых, можно открывать отдельные отчёты об 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 и о том, что из этого получилось.
Источник
Все о функциях разработчика в вашем телефоне
Константин Иванов
Настройки, которые используются для отладки и для разработки приложений, спрятаны в вашем телефоне – спрятаны в прямом смысле слова. Многие из нас идут в соответствующий раздел меню, чтобы запустить отладку USB или переключиться к рабочему модулю ART, но кроме этого, здесь имеется целый список настроек. Большая часть никогда вам не понадобится, но разве не интересно узнать, что скрывается в недрах вашего устройства?
«Разблокируем» функции разработчика в телефоне
Как говорилось выше, эти функции изначально скрыты. Это имеет смысл, поскольку найти их просто, а большинству людей они попросту не нужны. Для того, чтобы добраться до них, идем в раздел «Об устройстве» и ищем там пункт «Номер сборки». После пяти быстрых тапов появляется диалоговое окно – теперь устройство считает вас разработчиком. Только попробуйте ничего не испортить, ладно? Ну, или делайте что хотите – тоже вариант. Так или иначе, возможность заставить ваш телефон перестать работать всегда имеется.
А теперь посмотрим на предложенные функции повнимательнее.
Настройки
- Создать отчет об ошибках. Тапаете здесь, чтобы отправить соответствующее сообщение туда, куда вы хотите. Устройство готовит нужные файлы для отправки, что занимает пару минут, после чего вы видите уведомление. Если смахнуть его, процесс остановится, а если тапнуть, сообщение отправится.
- Пароль резервного копирования. Позволяет использовать ADB для создания бэкапа и восстановления приложений и связанных с ними данных на вашем компьютере. Резервное копирование данных требует введения пароля, и без него данные не могут быть восстановлены.
- Активный режим. Выбор этого пункта позволяет вам держать экран работающим постоянно при подключении телефона кабелем к зарядному устройству или к компьютеру по USB. Не стоит использовать этот пункт без надобности, поскольку это верный способ выжечь экран.
- Выбор рабочего модуля. Именно здесь вы можете выбрать между Dalvik и ART. Последний по-прежнему находится в тестовом режиме – это явно не то, что мы увидим в Android L. С некоторыми телефонами у него настоящий антагонизм, поэтому стоит уточнить на соответствующем форуме насчет вашей модели устройства.
- Включить журнал трансляции операций HCI Bluetooth. Иногда разработчику или специалисту по безопасности требуется перехватить и проанализировать пакеты Bluetooth HCI. Включение этого пункта помещает их в файл, который находится во встроенной памяти устройства (/sdcard/btsnoop_hci.log) для восстановления. После этого их можно проанализировать программой типа Wireshark.
- Статистика процессов. Все, что вам может понадобиться узнать о запущенных на вашем устройстве процессах. Тапаете здесь, а потом на одном из пунктов. Для обычного пользователя это просто набор цифр, но для разработчика может быть весьма полезным.
- Отладка USB. То, что позволяет вашему телефону связываться с компьютером, используя Android Debug Bridge (ADB). Это требуется для использования DDMS или команд ADB.
- Отозвать авторизацию отладки USB. Когда отладка при помощи компьютера происходит в первый раз, вам нужно авторизовать его и установить пару ключей. Эта настройка отменяет данное действие и предлагает повторить его снова.
- Отчеты об ошибках. Включает опцию, которая становится видимой, когда вы зажимаете кнопку питания для сбора и отправки отчета об ошибках. Очень удобно, если вы что-то тестируете.
- Фиктивные местоположения. Эта настройка позволяет вам вручную задавать информацию о местоположении, заставляя ваш телефон думать, что он там, где его в действительности нет. Кроме читов для Forsquare, это полезно для приложений, которые используют информацию о местоположении.
- Приложение для отладки. Эта настройка позволяет вам выбрать приложение для отладки. Вам не требуется действительно подключаться к отладчику, но если вы включите его, то не будете получать сообщений об ошибках, когда останавливаетесь на точке останова. Если вы не понимаете, что это значит, тогда эта настройка вам никогда не требовалась и не понадобится. Она создана для работы со средствами разработчика, позволяющими убедиться в том, что приложение работает корректно.
- Подождите, пока отладчик. Этот пункт остается неактивным, пока вы не выберет приложение для отладки. Когда оно установлено и выбрано, то настройка просто не позволяет выбранному приложению запуститься до тех пор, пока не включится отладчик. Еще один пункт, который нужен разработчикам, но бесполезен для большинства пользователей.
- Проверять для USB. Позволяет Google сканировать приложения, которые вы поставили через ADB, на предмет вредоносного поведения. Хорошая вещь.
- Показывать касания. Выбирая этот пункт, вы будете видеть визуальный эффект, подтверждающий регистрацию касания экрана.
- Местоположение указателя. Эта настройка размещает в верхней части экрана строку, в которой выводятся координаты точки экрана, которой коснулись последней.
- Показать обновления экрана. Заставляет край «окна» вспыхивать, когда происходит обновление контекста. Раздражает безумно.
- Показывать границы макета. Отмечает края элементов в окне диалога для того, чтобы вы знали, куда нужно нажать, чтобы активировать его. Попробуйте – и немедленно выключайте.
- Написание справа налево. Изменяет ориентацию экрана для поддержки языков с правосторонним написанием
- Анимация окна: масштаб. Устанавливает скорость воспроизведения анимации окна. Чем меньше число, тем быстрее.
- Анимация перехода: масштаб. Устанавливает скорость воспроизведения анимации при переходе. Опять же, чем меньше, тем быстрее.
- Эмуляция дополнительных дисплеев. Эта настройка позволяет разработчикам имитировать различные размеры экрана. Не самая надежная вещь.
- Рендеринг принудительно. Заставляет приложения использовать аппаратный двухмерный рендеринг, если они были написаны так, чтобы не использовать его по умолчанию. Иногда творит чудеса. Иногда отправляет все к чертям. Будьте бдительны.
- Показать обновления окна. С этой настройкой любая отрисовка, производимая графической подсистемой, получает красную подсветку.
- Показывать аппаратные обновления. Выделяет аппаратные уровни зеленым при обновлении. Зачем это нужно — можете почитать здесь http://www.curious-creature.org/2013/09/13/optimizing-hardware-layers/ (на английском).
- Отладка наложения. Наложение происходит каждый раз, когда приложение запрашивает систему на отрисовку чего-либо поверх чего-то иного. Эта настройка позволяет вам видеть, когда и где это происходит, чтобы видеть, в чем проблема.
- Включить 4х MSAA. Эта настройка принудительно включает множественную выборку сглаживания (MSAA). Как и с любым другим графическим ускорителем, чем больше сглаживания, тем лучше все смотрится. Но скорость работы при этом падает.
- Строгий режим. Эта настройка заставляет экран мигать, когда приложение использует главный поток для выполнения длительной и интенсивной операции.
- Выводить использование ЦП. Размещает в правом верхнем углу небольшое окно с информацией о центральном процессоре и его использовании. Забавная игрушка.
- Профиль обработки GPU. Эта настройка может либо рисовать график на экране, либо писать его в файл. График — визуальное отображение загрузки работы графического адаптера. Еще одна вещь, на которую интересно посмотреть.
- Включить трассеровку OpenGL. Настройка, позволяющая следить за ошибками OpenGL и помещающая их в специальный файл лога по вашему выбору. Ничего такого, что стоило бы трогать большинству пользователей.
- Не сохранять операции. Эта настройка уничтожает любое приложение, как только вы закрываете его окно. Ничего хорошего из этого не выйдет, что бы там на форумах ни писали.
- Фоновые процессы. Позволяет задавать в настройках количество процессов, которые могут одновременно работать в фоне. Еще одна вещь, которую большинству из нас не стоит трогать слишком часто. Если вообще стоит.
- Показать все ANR. Эта настройка заставляет все процессы показать сообщение «Приложение не отвечает», если приложение зависло, включает фоновые процессы, которые не запускаются пользователем. Полезно, если одно приложение мешает нормально работать другому.
Понятно, что большинству пользователей все эти настройки ни на что не сдались. Кроме того, лезть туда и нажимать на пункты меню ради самого процесса — не лучшая идея. Но всегда стоит знать, что вообще можно сделать, хотя бы и просто для того, чтобы не делать этого никогда.
Надеемся, что наш рассказ просветил вас немного по вопросу этих настроек и опций, записанных непонятными словами. Кстати, в зависимости от выбранного языка системы, производителя и версии ОС Android, набор пунктов может несколько отличаться разделами и их названиями.
Источник