ANR v Androidu: co to je, příčiny a metody odstranění

Autor: IT Sectr Publikováno: 2026-07-28 Doba čtení: 9 min

ANR (Application Not Responding) — je systémové oznámení Androidu, které se zobrazí, když aplikace nereaguje na vstup po dobu 5 sekund. Na rozdíl od glitchů (logické chyby bez blokování UI) a lagů (zpomalení bez úplného zastavení) je ANR kritická chyba zaznamenaná operačním systémem: Android zobrazí dialog „Aplikace nereaguje“ s nabídkou k zavření nebo čekání. Podle Android Vitals Documentation mají aplikace s mírou ANR nad 0,5 % nižší hodnocení v obchodě Google Play a mohou být skryty z doporučení. Diagnostika zahrnuje analýzu /data/anr/traces.txt, použití StrictMode a profilování hlavního vlákna.

Hlavní body

  • ANR — systémové oznámení Androidu při blokování hlavního vlákna déle než 5 sekund, vedoucí k dialogu „Aplikace nereaguje“
  • Hlavní příčiny — blokování hlavního vlákna (BroadcastReceiver, Service), deadlock mezi vlákny, dlouhá operace v ContentProvider
  • Diagnostika — analýza /data/anr/traces.txt, Android Studio Profiler, Firebase Performance Monitoring
  • Odstranění — přesun úloh do WorkManager, použití Kotlin Coroutines s Dispatchers.IO, StrictMode pro včasné odhalení
  • Prevence — omezení času BroadcastReceiver na 10 sekund, Service na 20 sekund, ContentProvider na 15 sekund

Co je ANR v Androidu

ANR (Application Not Responding) — je mechanismus ochrany uživatele v Androidu, který se aktivuje, když aplikace přestane reagovat na vstup. Systém sleduje dobu zpracování událostí: pokud BroadcastReceiver nedokončí onReceive do 10 sekund, Service se nevrátí z onCreate do 20 sekund a ContentProvider neodpoví do 15 sekund — Android vygeneruje ANR.

Jak ANR vypadá pro uživatele

Když dojde k ANR, Android zobrazí systémový dialog nad všemi okny: „Aplikace nereaguje. Chcete ji zavřít nebo počkat?“. Uživatel může aplikaci zavřít nebo počkat na její obnovení. Pokud se ANR často opakuje, uživatel aplikaci smaže. Google Play zohledňuje míru ANR — procento relací s ANR — v algoritmech řazení.

Rozdíl mezi ANR a zamrzáním na iOS

Na iOS neexistuje ekvivalent ANR se systémovým dialogem. Místo toho Apple používá Watchdog, který ukončí proces aplikace kódem 0x8badf00d. Uživatel nevidí žádný dialog — aplikace se jednoduše zavře na hlavní obrazovku. To činí ANR na Androidu pro uživatele viditelnějším, ale poskytuje systému více informací pro diagnostiku.

Hlavní příčiny ANR

K ANR dochází, když systém sleduje časový limit pro jednu ze čtyř typů komponent. Každá komponenta má svůj vlastní časový limit.

Blokování v BroadcastReceiver

BroadcastReceiver se spouští v hlavním vlákně. Pokud onReceive spustí synchronní síťový požadavek, dlouhou operaci zápisu do databáze nebo čeká na blokování — po 10 sekundách dojde k ANR. Řešení: použijte goAsync() a WorkManager pro zpracování na pozadí. Typický scénář — přijetí Push oznámení z FCM a synchronní ukládání do Room.

Dlouhá operace v Service

Service.onCreate a Service.onStartCommand mají limit 20 sekund. Pokud služba spustí těžkou inicializaci (načítání knihoven, čtení konfigurace ze sítě) v hlavním vlákně — ANR je nevyhnutelný. Použijte IntentService (zastaralý) nebo WorkManager pro zaručené provedení ve vlákně na pozadí.

ContentProvider s dlouhou inicializací

ContentProvider.onCreate se provádí před voláním Application.onCreate a má limit 15 sekund. Pokud poskytovatel provádí migraci databáze, načítání slovníků nebo inicializaci SDK ze sítě — způsobuje to ANR při spouštění aplikace. Řešení: líná inicializace, přesun těžkých operací do WorkManager.

  • BroadcastReceiver — 10 sekund na onReceive; použijte goAsync() pro zpracování na pozadí
  • Service — 20 sekund na onCreate/onStartCommand; použijte WorkManager nebo CoroutineWorker
  • ContentProvider — 15 sekund na onCreate; přesuňte inicializaci do Application.onCreate s odloženým spuštěním
  • UI vlákno — 5 sekund bez zpracování událostí; jakékoli blokování delší než 5 sekund způsobí ANR

Jak diagnostikovat ANR

Android poskytuje několik nástrojů pro analýzu ANR: od systémových protokolů po specializované knihovny.

Analýza traces.txt

Při každém ANR Android ukládá soubor /data/anr/traces.txt s výpisem zásobníků všech vláken aplikace. Najděte vlákno „main“ — poslední metoda v zásobníku ukazuje příčinu. Typické vzory: Thread.sleep(), InputStream.read(), BinderProxy.transact(). Pro extrakci souboru ze zařízení použijte adb s právy superuživatele.

Firebase Crashlytics s hlášeními ANR

Firebase Crashlytics automaticky shromažďuje ANR a zobrazuje je na dashboardu spolu se stopováním. Pro Android 11+ přicházejí hlášení ANR s úplným zásobníkem hlavního vlákna. Integrace vyžaduje přidání závislosti a inicializaci FirebaseApp v Application.onCreate.

Android Studio Profiler se stopováním vláken

CPU Profiler v Android Studio umožňuje zaznamenat stopování činnosti aplikace a zjistit, které metody zabírají čas CPU. Zapněte „Record with method traces“ a reprodukujte scénář způsobující ANR. Na časové ose bude viditelné, které metody byly spouštěny v hlavním vlákně v okamžiku zamrznutí.

Příklad integrace Firebase Crashlytics pro sběr ANR na Androidu:

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

Metody odstranění ANR

Odstranění ANR znamená především přesun všech dlouhých operací z hlavního vlákna do vláken na pozadí. Podívejme se na konkrétní techniky pro každý typ komponenty.

Použití WorkManager pro úlohy na pozadí

WorkManager — doporučené řešení od Google pro práci na pozadí. Zaručuje provedení úlohy ve vlákně na pozadí s ohledem na stav zařízení. Na rozdíl od Service WorkManager neblokuje hlavní vlákno a je odolný vůči restartu aplikace. Pro BroadcastReceiver použijte goAsync() a předejte výsledek PendingResult do WorkManager.

Kotlin Coroutines se správnými dispečery

Spouštějte všechny síťové požadavky, práci s databází a operace se soubory s Dispatchers.IO. Hlavní vlákno by mělo pouze aktualizovat UI. Použijte viewModelScope pro automatické zrušení korutin při zničení Activity. Vyhněte se runBlocking() v jakémkoli kontextu — to je synchronní blokování aktuálního vlákna.

Líná inicializace ContentProvider

Pokud ContentProvider provádí dlouhou inicializaci, použijte mechanismus odloženého načítání: vytvořte poskytovatele, který okamžitě vrací data, a těžkou inicializaci spusťte prostřednictvím WorkManager se zpožděním. Tím se zabrání ANR při spouštění aplikace, kdy je systém nejcitlivější na zpoždění.

Příklad správného použití BroadcastReceiver s goAsync v Androidu:

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()
    }
}

Prevence ANR při vývoji

Nejlepší způsob boje proti ANR je předcházet jejich vzniku ve fázi vývoje pomocí nástrojů a architektonických řešení.

StrictMode pro odhalování blokování hlavního vlákna

StrictMode s aktivovanými politikami detectNetwork() a detectDiskReads()/detectDiskWrites() odhaluje potenciální ANR ve fázi vývoje. V sestavení Debug nastavte penaltyDeath — jakékoli porušení povede k okamžitému pádu a vývojář uvidí problém před potvrzením změn.

Firebase Performance Monitoring pro produkční metriky

Firebase Performance sleduje dobu provádění klíčových operací a ukazuje, které scénáře překračují práh ANR. Nakonfigurujte vlastní stopování pro každou obrazovku a síťový požadavek. Pokud doba provádění přesáhne 3 sekundy — jedná se o potenciální ANR vyžadující optimalizaci.

Testování se zpožděním sítě a disku

Simulujte pomalé podmínky: omezte rychlost sítě pomocí Network Link Conditioner na iOS nebo Android Emulator. Zpomalte čtení z disku pomocí emulace pomalé paměti. ANR se často objevuje právě za takových podmínek, na rychlých zařízeních vývojáře není viditelný.

  • BroadcastReceiver — vždy používejte goAsync() pro zpracování delší než 1 sekunda
  • Service — nahraďte WorkManager nebo CoroutineWorker s dispečerem na pozadí
  • ContentProvider — vyhněte se síti a databázi v onCreate, použijte lazy-init s WorkManager
  • UI vlákno — StrictMode s penaltyDeath v Debug, Firebase Performance pro produkční monitorování

Často kladené otázky

Proč k ANR dochází na Androidu, ale ne na iOS?

Android explicitně sleduje dobu zpracování událostí v hlavním vlákně a zobrazuje dialog ANR. iOS používá Watchdog, který při zamrznutí delším než 10–20 sekund vynutí uzavření aplikace. ANR je vlastnost architektury Androidu, kde několik komponent (BroadcastReceiver, Service) má přísné časové limity.

Jak najít traces.txt na zařízení bez rootu?

Na Android 11+ můžete získat výpis ANR pomocí adb shell dumpsys dropbox --print data_app_anr. Na Android 10 a nižším bez rootu není přístup k /data/anr/traces.txt. Použijte Firebase Crashlytics — automaticky shromažďuje hlášení ANR pro Android 11+.

Jaká míra ANR je považována za přijatelnou?

Google Play doporučuje míru ANR nižší než 0,5 % — tedy ne více než 5 ANR na 1000 relací. Aplikace s mírou nad 1 % obdrží varování v konzoli Google Play Console a může být skryta z doporučení. Ideálně by míra ANR měla být pod 0,1 %.

Může korutina způsobit ANR?

Korutina sama o sobě neblokuje vlákno. Ale pokud je uvnitř korutiny spuštěno runBlocking v hlavním vlákně nebo je korutina spuštěna s Dispatchers.Main a provádí dlouhou operaci CPU — způsobí to ANR. Používejte Dispatchers.IO pro vstup-výstup a Dispatchers.Default pro výpočty.

Jak testovat ANR v emulátoru?

Použijte Android Emulator s profilem „Slow Network“ nebo napište test, který volá Thread.sleep(6000) v hlavním vlákně. Spusťte aplikaci přes Debug a po 5 sekundách uvidíte dialog ANR. Zkontrolujte, že se v logcat objevil záznam ANR se stopováním.

Shrnutí

  • ANR — systémové oznámení Androidu při blokování hlavního vlákna déle než 5 sekund nebo překročení časových limitů komponent
  • Časové limity: BroadcastReceiver — 10 s, Service — 20 s, ContentProvider — 15 s, UI — 5 s
  • Diagnostika — /data/anr/traces.txt, Firebase Crashlytics, CPU Profiler v Android Studio
  • Odstranění — WorkManager, goAsync(), Kotlin Coroutines s Dispatchers.IO, líná inicializace ContentProvider
  • Prevence — StrictMode s penaltyDeath, Firebase Performance Monitoring, testování se zpožděním sítě
  • Google Play doporučuje míru ANR < 0,5 %; při míře > 1 % aplikace podléhá omezením viditelnosti
  • Doporučení: nakonfigurujte Firebase Crashlytics a Performance pro sběr ANR v produkci a nastavte upozornění při překročení prahu 0,3 %

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také