ANR в разработката под Android — какво е, причини и начини за поправка

Автор: IT Sectr Публикувано: 2026-03-28 Време за четене: 9 мин

ANR (Application Not Responding) — това е системно известие на Android, което се появява, когато приложението спре да реагира на потребителския вход за повече от 5 секунди. Според Android Developers, основната причина са дълги операции в главната нишка, блокиращи обработката на докосвания и изобразяването на интерфейса. Разбирането на механизмите на ANR е необходимо за всеки Android разработчик, за да създава отзивчиви приложения.

Основни точки

  • ANR — системно предупреждение на Android при замръзване на приложението за повече от 5 секунди
  • Главната нишка (UI-нишка) — единственото място, където блокирането води до ANR
  • InputDispatcher — компонент на системата, който отчита забавяне на входа и инициира ANR
  • traces.txt — ключов файл за диагностика на причината за замръзване на устройството
  • StrictMode — вграден инструмент на Android за откриване на дълги операции в UI-нишката

Какво е ANR

ANR (Application Not Responding) — диалогов прозорец на операционната система Android, който се появява, когато приложението спре да отговаря на потребителския вход. Системата следи времето за обработка на събития чрез InputDispatcher: ако докосване или натискане на бутон не бъде обработено за 5 секунди, Android показва диалог с предложение да затворите или изчакате приложението.

Механизмът ANR защитава потребителското изживяване от замръзнали приложения. Android не позволява на едно приложение да блокира цялата система — за разлика от Desktop-ОС, мобилната платформа принудително ограничава времето за обработка на събития. BroadcastReceiver има лимит от 10 секунди, а foreground услугата — 20 секунди.

ANR НЕ е изключение в кода — това е системен механизъм на ниво Linux процеси. Android изпраща сигнал SIGQUIT на процеса, след което системата запазва стека на извикванията на всички нишки във файла traces.txt. Разработчикът получава ANR не като catch-изключение, а като отчет след рестартиране на приложението. На Android 11+ се появи API ApplicationExitInfo, който позволява програмно да получите причината за прекратяване на процеса, включително ANR — това опростява събирането на статистика без ръчно анализиране на traces.txt.

Основни причини за ANR

Пет категории операции водят стабилно до ANR в Android приложенията. Всяка от тях блокира главната нишка, не позволявайки на системата да обработва събития на входа и да прерисува екрана.

Мрежови заявки в главната нишка

Синхронни HTTP заявки, изпълнени в UI-нишката, са най-честата причина за ANR при начинаещи разработчици. Дори бърза заявка към сървъра може да отнеме 1–3 секунди, а при лоша връзка — 30 секунди или повече. Android изрично забранява мрежовите операции в главната нишка от API 11, хвърляйки NetworkOnMainThreadException.

Използвайте Coroutines или RxJava за асинхронни извиквания. Корутините с диспечер Dispatchers.IO изпълняват заявката във фонова нишка, а резултатът се предава на главната чрез Dispatchers.Main. Това напълно елиминира блокирането на UI-нишката от мрежови операции.

kotlin
fun fetchUserData() {
    CoroutineScope(Dispatchers.Main).launch {
        val result = withContext(Dispatchers.IO) {
            api.getUserData() // фонова операция
        }
        updateUI(result) // резултат върху главната нишка
    }
}

Интензивни изчисления в UI-нишката

Обработка на големи масиви от данни, парсване на JSON или XML, работа с bitmap директно в главната нишка — втората по честота причина за ANR. Дори 300 милисекунди непрекъсната работа на UI-нишката без връщане в цикъла на събития причиняват забележимо забавяне на изобразяването, а граничната стойност от 5 секунди се регистрира като ANR.

WorkManager и фоновите услуги са предназначени за изнасяне на тежки изчисления от главната нишка. Използвайте AsyncTask (остарял), ListenableFuture или Kotlin Flow за предаване на данни на порции, без да блокирате UI.

Заключвания за синхронизация и Deadlock

Deadlock възниква, когато две нишки държат заключвания и чакат една друга. Ако една от нишките е главната, системата регистрира ANR точно след 5 секунди. Thread.join(), CountDownLatch.await() и synchronized-блокове, извиквани от UI-нишката, носят риск от блокиране.

Избягвайте всякакви блокиращи операции в главната нишка. Вместо synchronized използвайте ConcurrentHashMap, вместо Thread.join() — корутини с async/await. Това правило важи за всеки език в Android: Java, Kotlin или C++ чрез JNI.

Продължителна работа на BroadcastReceiver

BroadcastReceiver се изпълнява в главната нишка по подразбиране. Ако onReceive() е зает повече от 10 секунди, Android показва ANR. Зареждането на данни от базата данни или мрежата вътре в onReceive е гарантиран път към замръзване.

Използвайте goAsync() вътре в BroadcastReceiver за превключване към фонова нишка или registerReceiver с getBackgroundBroadcastReceiver(). Това позволява обработка на събития без блокиране на UI.

ContentProvider и SQLite в главната нишка

Тежки заявки към ContentProvider или директна работа с SQLite в UI-нишката — по-малко очевидна, но честа причина за ANR. При миграция на база данни или масово вмъкване на хиляди записи времето за изпълнение може да надхвърли 5-секундния лимит.

Прехвърлете всички операции с базата данни във фонови нишки чрез Room с suspend-функции. Room автоматично проверява дали заявката не се изпълнява в главната нишка и хвърля изключение при нарушение.

Как да диагностираме ANR

Диагностиката на ANR се различава от отстраняването на обикновени изключения — не можете да хванете ANR в try-catch. Основният източник на информация е файлът traces.txt, който Android създава в момента на замръзване.

traces.txt съдържа стека на извикванията на всички нишки на приложението в момента на ANR. За да прочетете файла от реално устройство, изпълнете командата adb bugreport, която събира пълен системен отчет, включващ всички ANR от последно време. За емулатора файлът е достъпен в /data/anr/traces.txt. Стекът на извикванията показва кой метод се е изпълнявал в главната нишка в момента на блокирането.

text
adb bugreport bugreport.zip
unzip -p bugreport.zip "*traces*" > traces.txt

Google Play Console предоставя раздел ANR & Crash с обобщени отчети и честоти на грешки. За всеки ANR се показва стек на извикванията и статистика по устройства: модел, версия на Android, регион. Това позволява откриване на ANR, които зависят от конкретни устройства или версии на системата.

Android Studio от 2021 г. съдържа ANR Watchdog в профилиращия инструмент. Той автоматично записва dump на нишките, ако главната нишка не отговаря повече от праговото време. Инструментът показва времева линия на събитията: кои операции са стартирани, кои методи са се изпълнявали и на кой етап е настъпило блокирането.

Как да предотвратим ANR

Профилактиката на ANR се основава на едно фундаментално правило: главната нишка трябва да обработва само UI събития. Всяка операция, по-дълга от 16 милисекунди (времето на един кадър), трябва да се изпълнява във фонова нишка.

StrictMode — автоматична проверка

StrictMode — вграден инструмент на Android за откриване на потенциални ANR на етапа на разработка. Включете го в Application.onCreate() с флагове за дисковови и мрежови операции. При нарушение StrictMode хвърля изключение или пише в logcat.

kotlin
if (BuildConfig.DEBUG) {
    StrictMode.ThreadPolicy.Builder()
        .detectDiskReads()
        .detectDiskWrites()
        .detectNetwork()
        .penaltyLog()
        .build()
        .let { StrictMode.setThreadPolicy(it) }
}

Асинхронни модели: Coroutines и RxJava

Kotlin Coroutines — стандартният начин за асинхронна работа в съвременни Android приложения. Основен похват: I/O операциите се изпълняват на Dispatchers.IO, резултатът се предава на Dispatchers.Main за обновяване на UI. За Flow-подобни сценарии използвайте Dispatchers.Default за CPU-интензивни задачи.

RxJava остава популярен в наследени проекти. subscribeOn(Schedulers.io()) и observeOn(AndroidSchedulers.mainThread()) — минималният набор за предотвратяване на ANR. Същото правило: нито едно Observable или Flowable не трябва да излъчва данни от главната нишка.

Мониторинг в продукция

Firebase Crashlytics от версия SDK 18.4.0 поддържа ANR мониторинг веднага след инсталиране. За Android 11+ Crashlytics използва системния API ApplicationExitInfo, който предоставя точната причина за прекратяване: ANR, Crash или системно убиване. Включете собствени ключове с параметри на екрана и състоянието за контекстуален анализ.

Инструменти за откриване на ANR

Пет инструмента покриват всички етапи на работа с ANR: от отстраняване на работната станция до мониторинг в продукция. Всеки инструмент решава своя задача и предоставя данни за различни сценарии.

ИнструментПредназначениеФормат на данни
StrictModeОткриване на етапа на разработкаLogcat / Exception
ANR Watchdog (Android Studio)Трасиране в реално времеThread dump + timeline
Google Play ConsoleОбобщена статистикаANR rate + stack traces
Firebase CrashlyticsПродукционен мониторингApplicationExitInfo
adb bugreportПълен системен отчетtraces.txt + logcat + dmesg

Всеки инструмент има своя ниша: StrictMode открива очевидни нарушения в ранните етапи, Crashlytics показва реалната честота на ANR при потребителите, а adb bugreport дава най-пълната картина за сложни случаи. Комбинирайте ги за пълно покритие.

Firebase Performance Monitoring

Firebase Performance следи времето за отговор на UI-нишката и автоматично създава traces за подозрително дълги операции. Ако главната нишка блокира за повече от 500 ms, Performance записва персонализиран trace с името на метода-причина. Това позволява откриване на ANR сценарии без участие на потребителя и преди да станат критични.

Интеграцията с Firebase Crashlytics дава пълна картина: Performance показва забавяния преди ANR, а Crashlytics — самия факт на замръзване. Настройте аларми в Firebase Console за събитие ANR rate над 0.1% и ще получавате известия за нови проблеми преди масови потребителски жалби.

Често задавани въпроси

Каква е разликата между ANR и Crash?

ANR — замръзване, при което приложението не отговаря, но остава в паметта. Crash — пълно аварийно прекратяване с изход от процеса. ANR може да бъде „преживяно“, ако системата или потребителят изчакат отговор, докато Crash винаги прекратява приложението.

Може ли да се хване ANR чрез try-catch?

Не. ANR не е изключение на Java/Kotlin, а сигнал на системата на ниво процеси (SIGQUIT). Разработчикът не може да го обработи в кода на приложението. Единственият начин да реагирате на ANR е да анализирате отчети след рестартиране.

Защо ANR се появява на едни устройства, но не и на други?

Производителността на устройството, версията на Android, натоварването на CPU и броят на фоновите процеси влияят на вероятността за ANR. На слаби устройства същата операция може да отнеме 2–3 пъти повече време, надхвърляйки 5-секундния лимит.

Какъв е лимитът от време за BroadcastReceiver преди ANR?

10 секунди за обикновен BroadcastReceiver в onReceive(). За foreground услуги лимитът е 20 секунди, а за ContentProvider няма ясен лимит, но блокирането на главната нишка за повече от 5 секунди все пак причинява ANR.

Какво да правим, ако ANR се случва рядко и не се възпроизвежда?

Включете StrictMode във всички debug версии, добавете мониторинг чрез Firebase Crashlytics и използвайте adb bugreport, когато ANR се случи. Нередовните ANR често са свързани с условия на състезание (race condition) или специфични мрежови състояния.

Обобщение

  • ANR — системен механизъм на Android, задействащ се при блокиране на главната нишка за повече от 5 секунди
  • Главната нишка трябва да се занимава само с UI — всички останали операции се изнасят във фонови нишки
  • Диагностиката на ANR се извършва чрез traces.txt, Google Play Console и Firebase Crashlytics
  • StrictMode открива потенциални ANR на етапа на разработка без стартиране на реално устройство
  • Coroutines с Dispatchers.IO — стандартният начин за асинхронна работа в съвременни Android проекти
  • BroadcastReceiver изисква goAsync() или фонови регистратор за работа над 10 секунди
  • ANR в продукция се мониторира чрез Crashlytics и вградения API ApplicationExitInfo на Android 11 и по-нови

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също