Настройка мониторинга ANR (Application Not Responding) в Android-приложении

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Настройка мониторинга ANR (Application Not Responding) в Android-приложении
Средняя
от 4 часов до 2 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1054
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    874
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    445

Настройка мониторинга ANR (Application Not Responding) в Android-приложении

ANR происходит, когда main thread не отвечает на input-событие дольше 5 секунд или BroadcastReceiver не завершается за 10 секунд. Система убивает диалог «Ждать/Завершить», пользователь видит зависший экран, а в Crashlytics появляется запись без стека вызовов — только ANR и имя Activity. Это худший вариант: крэш хотя бы показывает трейс.

Откуда берутся ANR

Чаще всего — это не один тяжёлый вызов, а цепочка: корутина запускается на Dispatchers.Main, вызывает runBlocking, внутри которого стоит Room.database.query() без suspend. На слабом устройстве с занятым диском это 5+ секунд блокировки.

Второй по частоте источник: SharedPreferences через getSharedPreferences() при холодном старте. На Android 7–9 на бюджетных устройствах первое чтение из SharedPreferences блокирует main thread до 800ms, если файл не в page cache.

// Антипаттерн — чтение SharedPreferences на main thread при старте
class SplashActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val token = getSharedPreferences("prefs", MODE_PRIVATE)
            .getString("auth_token", null) // блокирует main thread
    }
}

Правильно: вынести в DataStore (корутинный) или читать в lifecycleScope.launch(Dispatchers.IO).

Инструменты для мониторинга ANR

Firebase Crashlytics с AnrDetector — самый простой путь, если Crashlytics уже подключён. Crashlytics регистрирует ANR через ApplicationExitInfo API (доступен с API 30). На Android < 30 — через собственный watchdog-поток.

// Crashlytics ANR автоматически, если подключён
implementation("com.google.firebase:firebase-crashlytics:18.+")

Sentry детектирует ANR через watchdog: запускает поток, который каждые 1000ms проверяет, жив ли main thread. Если нет ответа > anrTimeoutIntervalMillis — снимает stack trace.

SentryAndroid.init(this) { options ->
    options.dsn = "https://[email protected]/project"
    options.isAnrEnabled = true
    options.anrTimeoutIntervalMillis = 5000
    options.isAnrReportInDebug = false // не спамим в debug
}

Android Vitals в Google Play Console — агрегированные данные из продакшена без SDK. Показывает ANR Rate по версиям и типу устройства. Порог «плохого поведения» — > 0.47% ANR Rate от ежедневных активных пользователей.

Диагностика через StrictMode

В debug-сборке StrictMode помогает поймать потенциальные ANR до продакшена:

if (BuildConfig.DEBUG) {
    StrictMode.setThreadPolicy(
        StrictMode.ThreadPolicy.Builder()
            .detectAll()
            .penaltyLog()
            .penaltyFlashScreen()
            .build()
    )
    StrictMode.setVmPolicy(
        StrictMode.VmPolicy.Builder()
            .detectLeakedSqlLiteObjects()
            .detectLeakedClosableObjects()
            .penaltyLog()
            .build()
    )
}

penaltyFlashScreen() — подсвечивает экран красным при каждой disk read на main thread. Раздражает, но работает: разработчик видит проблему немедленно, а не через неделю в Crashlytics.

ApplicationExitInfo — точный источник трейсов

С API 30 Android сохраняет причину завершения процесса в ApplicationExitInfo. Это намного точнее watchdog-потоков:

val activityManager = getSystemService(ActivityManager::class.java)
val exitReasons = activityManager.getHistoricalProcessExitReasons(null, 0, 10)

exitReasons.filter { it.reason == ApplicationExitInfo.REASON_ANR }.forEach { info ->
    info.traceInputStream?.use { stream ->
        val trace = stream.bufferedReader().readText()
        // отправляем trace в ваш мониторинг
        Log.e("ANR", trace)
    }
}

traceInputStream содержит полный thread dump в момент ANR — те же данные, что в /data/anr/traces.txt. Можно прочитать при следующем запуске приложения и отправить в Sentry/Datadog как attachment.

Настройка алертов

В Firebase Crashlytics настраиваем velocity alert на ANR:

  • Порог: > 1% crash-free sessions affected за 1 час
  • Канал: Slack webhook через Firebase Alert Channels

В Sentry аналогично через Issue Alerts с условием event.type:transaction AND event.tags.mechanism:ANR.

Что делаем

  • Подключаем ANR-детектор через Sentry или Crashlytics (или оба — они не конфликтуют)
  • Настраиваем чтение ApplicationExitInfo на API 30+ для точных трейсов
  • Включаем StrictMode в debug-сборке для превентивной диагностики
  • Конфигурируем velocity alerts с нотификацией в Slack
  • Анализируем Android Vitals baseline для сравнения с конкурентами в категории

Сроки

Базовая настройка: 4 часа – 1 день. С анализом ApplicationExitInfo и дашбордом: 2 дня. Стоимость рассчитывается индивидуально.