ANR у Android-у: шта је то, узроци и методе отклањања

Аутор: IT Sectr Објављено: 2026-07-28 Време читања: 9 мин

ANR (Application Not Responding) — системско обавештење Android-а које се појављује када апликација не реагује на унос током 5 секунди. За разлику од глукова (логичке грешке без блокирања UI) и лагова (успоравање без потпуног заустављања), ANR је критични квар који бележи оперативни систем: Android приказује дијалог „Апликација не реагује” са предлогом да је затворите или сачекате. Према Android Vitals Documentation, апликације са ANR стопом изнад 0,5% имају нижи рејтинг у Google Play-у и могу бити сакривене из препорука. Дијагностика укључује анализу /data/anr/traces.txt, коришћење StrictMode и профилисање главне нити.

Главно

  • ANR — системско обавештење Android-а при блокирању главне нити дуже од 5 секунди, које води до дијалога „Апликација не реагује”
  • Основни узроци — блокирање главне нити (BroadcastReceiver, Service), deadlock између нити, дуга операција у ContentProvider-у
  • Дијагностика — анализа /data/anr/traces.txt, Android Studio Profiler, Firebase Performance Monitoring
  • Отклањање — пребацивање задатака у WorkManager, коришћење Kotlin Coroutines са Dispatchers.IO, StrictMode за рано откривање
  • Превенција — ограничавање времена BroadcastReceiver-а на 10 секунди, Service-а на 20 секунди, ContentProvider-а на 15 секунди

Шта је ANR у Android-у

ANR (Application Not Responding) — механизам заштите корисника у Android-у који се активира када апликација престане да реагује на унос. Систем прати време обраде догађаја: ако BroadcastReceiver не заврши onReceive у 10 секунди, Service се не врати из onCreate за 20 секунди, а ContentProvider не одговори за 15 секунди — Android генерише ANR.

Како ANR изгледа за корисника

Када настане ANR, Android приказује системски дијалог изнад свих прозора: „Апликација не реагује. Затворити је или сачекати?”. Корисник може да затвори апликацију или сачека њен опоравак. Ако се ANR често понавља, корисник брише апликацију. Google Play узима у обзир ANR стопу — проценат сесија са ANR-ом — у алгоритмима рангирања.

Разлика између ANR-а и замрзавања на iOS-у

На iOS-у не постоји аналог ANR-а са системским дијалогом. Уместо тога, Apple користи Watchdog, који завршава процес апликације кодом 0x8badf00d. Корисник не види дијалог — апликација се једноставно затвара на главни екран. То чини ANR на Android-у видљивијим за корисника, али даје систему више информација за дијагностику.

Основни узроци ANR-а

ANR настаје када систем прати тајмаут за једну од четири врсте компоненти. Свака компонента има своје временско ограничење.

Блокирање у BroadcastReceiver-у

BroadcastReceiver се извршава у главној нити. Ако onReceive покрене синхрони мрежни захтев, дугу операцију уписа у базу или чека на блокаду — после 10 секунди настаје ANR. Решење: користите goAsync() и WorkManager за обраду у позадини. Типичан сценариј — примање Push обавештења од FCM-а и синхроно чување у Room-у.

Дуга операција у Service-у

Service.onCreate и Service.onStartCommand имају лимит од 20 секунди. Ако сервис покреће тешку иницијализацију (учитавање библиотека, читање конфигурације из мреже) у главној нити — ANR је неизбежан. Користите IntentService (застарео) или WorkManager за гарантовано извршење у позадинској нити.

ContentProvider са дугом иницијализацијом

ContentProvider.onCreate се извршава пре позива Application.onCreate и има лимит од 15 секунди. Ако провајдер врши миграцију базе, учитавање речника или иницијализацију SDK-а из мреже — то изазива ANR при покретању апликације. Решење: lazy-иницијализација, пребацивање тешких операција у WorkManager.

  • BroadcastReceiver — 10 секунди за onReceive; користите goAsync() за позадинску обраду
  • Service — 20 секунди за onCreate/onStartCommand; користите WorkManager или CoroutineWorker
  • ContentProvider — 15 секунди за onCreate; преместите иницијализацију у Application.onCreate са одложеним покретањем
  • UI нит — 5 секунди без обраде догађаја; свако блокирање дуже од 5 секунди изазива ANR

Како дијагностиковати ANR

Android пружа неколико алата за анализу ANR-а: од системских дневника до специјализованих библиотека.

Анализа traces.txt

При сваком ANR-у, Android чува датотеку /data/anr/traces.txt са одливом стекова свих нити апликације. Пронађите нит „main” — последњи метод у стеку указује на узрок. Типични обрасци: Thread.sleep(), InputStream.read(), BinderProxy.transact(). За издвајање датотеке са уређаја користите adb са суперкорисничким правима.

Firebase Crashlytics са ANR извештајима

Firebase Crashlytics аутоматски прикупља ANR и приказује их на контролној табли заједно са трасирањем. За Android 11+, ANR извештаји стижу са комплетним стеком главне нити. Интеграција захтева додавање зависности и иницијализацију FirebaseApp у Application.onCreate.

Android Studio Profiler са трасирањем нити

CPU Profiler у Android Studio-у омогућава снимање трасирања рада апликације и увид у то који методи заузимају процесорско време. Укључите „Record with method traces” и репродукујте сценариј који изазива ANR. На временској линији ће бити видљиво који су се методи извршавали у главној нити у тренутку замрзавања.

Пример интеграције Firebase Crashlytics-а за прикупљање ANR-а на Android-у:

kotlin
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        FirebaseApp.initializeApp(this)
        FirebaseCrashlytics.getInstance()
            .setCrashlyticsCollectionEnabled(true)
        StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
            .detectAll()
            .penaltyLog()
            .build())
    }
}

Методе отклањања ANR-а

Отклањање ANR-а је пре свега пребацивање свих дугих операција из главне нити у позадинске. Размотримо конкретне технике за сваку врсту компоненте.

Коришћење WorkManager-а за позадинске задатке

WorkManager — Google-ово препоручено решење за рад у позадини. Гарантује извршење задатка у позадинској нити узимајући у обзир стање уређаја. За разлику од Service-а, WorkManager не блокира главну нит и отпоран је на поновно покретање апликације. За BroadcastReceiver користите goAsync() и пренесите резултат PendingResult у WorkManager.

Kotlin Coroutines са правим диспечерима

Покрећите све мрежне захтеве, рад са базом и операције са датотекама са Dispatchers.IO. Главна нит треба само да ажурира UI. Користите viewModelScope за аутоматско отказивање корутина при уништењу Activity-ја. Избегавајте runBlocking() у било ком контексту — то је синхроно блокирање тренутне нити.

Lazy-иницијализација ContentProvider-а

Ако ContentProvider врши дугу иницијализацију, користите механизам одложеног учитавања: направите провајдер који враћа податке одмах, а тешку иницијализацију покрените кроз WorkManager са закашњењем. Ово спречава ANR при покретању апликације, када је систем најосетљивији на кашњења.

Пример правилног коришћења BroadcastReceiver-а са goAsync у Android-у:

kotlin
class FcmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        val pendingResult = goAsync()
        WorkManager.getInstance(context!!)
            .enqueue(OneTimeWorkRequest.from(NotificationWorker::class.java))
        pendingResult.finish()
    }
}

Превенција ANR-а у развоју

Најбољи начин борбе против ANR-а је спречавање њиховог појављивања у фази развоја кроз алате и архитектонска решења.

StrictMode за откривање блокирања главне нити

StrictMode са укљученим политикама detectNetwork() и detectDiskReads()/detectDiskWrites() открива потенцијалне ANR у фази развоја. У Debug верзији подесите penaltyDeath — свако кршење ће довести до тренутног пада, а програмер ће видети проблем пре комитовања.

Firebase Performance Monitoring за производне метрике

Firebase Performance прати време извршења кључних операција и показује који сценарији прелазе праг ANR-а. Подесите прилагођена трасирања за сваки екран и мрежни захтев. Ако време извршења прелази 3 секунде — то је потенцијални ANR који захтева оптимизацију.

Тестирање са кашњењима мреже и диска

Симулирајте споре услове: ограничите брзину мреже преко Network Link Conditioner-а на iOS-у или Android Emulator-у. Успорите читање са диска кроз емулацију споре меморије. ANR се често појављује управо у таквим условима, на брзим уређајима програмера није видљив.

  • BroadcastReceiver — увек користите goAsync() за обраду дужу од 1 секунде
  • Service — замените WorkManager-ом или CoroutineWorker-ом са позадинским диспечером
  • ContentProvider — избегавајте мрежу и базу у onCreate, користите lazy-init са WorkManager-ом
  • UI нит — StrictMode са penaltyDeath у Debug, Firebase Performance за производни мониторинг

Често постављана питања

Зашто ANR настаје на Android-у, али не на iOS-у?

Android експлицитно прати време обраде догађаја на главној нити и приказује дијалог ANR. iOS користи Watchdog, који присилно затвара апликацију при замрзавању дужем од 10–20 секунди. ANR је карактеристика архитектуре Android-а, где неколико компоненти (BroadcastReceiver, Service) имају строге тајмауте.

Како пронаћи traces.txt на уређају без root-а?

На Android 11+ можете добити ANR дамп кроз adb shell dumpsys dropbox --print data_app_anr. На Android 10 и нижем без root-а нема приступа /data/anr/traces.txt. Користите Firebase Crashlytics — аутоматски прикупља ANR извештаје за Android 11+.

Која ANR стопа се сматра прихватљивом?

Google Play препоручује ANR стопу мању од 0,5% — односно не више од 5 ANR на 1000 сесија. Апликација са стопом изнад 1% добија упозорење у Google Play Console и може бити сакривена из препорука. Идеално, ANR стопа треба да буде испод 0,1%.

Може ли корутина изазвати ANR?

Корутина сама по себи не блокира нит. Али ако се унутар корутине извршава runBlocking на главној нити или је корутина покренута са Dispatchers.Main и извршава дугу CPU операцију — то ће изазвати ANR. Користите Dispatchers.IO за улаз-излаз и Dispatchers.Default за прорачуне.

Како тестирати ANR у емулатору?

Користите Android Emulator са профилом „Slow Network” или напишите тест који позива Thread.sleep(6000) на главној нити. Покрените апликацију кроз Debug и после 5 секунди ћете видети ANR дијалог. Проверите да се у logcat-у појавио запис о ANR-у са трасирањем.

Закључци

  • ANR — системско обавештење Android-а при блокирању главне нити дуже од 5 секунди или прекорачењу тајмаута компоненти
  • Тајмаути: BroadcastReceiver — 10 с, Service — 20 с, ContentProvider — 15 с, UI — 5 с
  • Дијагностика — /data/anr/traces.txt, Firebase Crashlytics, CPU Profiler у Android Studio-у
  • Отклањање — WorkManager, goAsync(), Kotlin Coroutines са Dispatchers.IO, lazy-иницијализација ContentProvider-а
  • Превенција — StrictMode са penaltyDeath, Firebase Performance Monitoring, тестирање са кашњењима мреже
  • Google Play препоручује ANR стопу < 0,5%; при стопи > 1% апликација подлеже ограничењима видљивости
  • Препорука: подесите Firebase Crashlytics и Performance за прикупљање ANR-а у продукцији и поставите упозорења при преласку прага од 0,3%

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође