ANR ve vývoji pro Android — co to je, příčiny a způsoby opravy

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

ANR (Application Not Responding) — je systémové upozornění Androidu, které se objeví, když aplikace přestane reagovat na uživatelský vstup déle než 5 sekund. Podle Android Developers jsou hlavní příčinou dlouhé operace na hlavním vlákně, které blokují zpracování dotyků a vykreslování rozhraní. Pochopení mechanismů ANR je nezbytné pro každého Android vývojáře k vytváření responzivních aplikací.

Hlavní body

  • ANR — systémové varování Androidu při zamrznutí aplikace déle než 5 sekund
  • Hlavní vlákno (UI vlákno) — jediné místo, kde blokování vede k ANR
  • InputDispatcher — systémová komponenta zaznamenávající zpoždění vstupu a iniciující ANR
  • traces.txt — klíčový soubor pro diagnostiku příčiny zamrznutí na zařízení
  • StrictMode — vestavěný nástroj Androidu pro detekci dlouhých operací na UI vlákně

Co je ANR

ANR (Application Not Responding) — je dialogové okno operačního systému Android, které se objeví, když aplikace přestane odpovídat na uživatelský vstup. Systém sleduje dobu zpracování událostí prostřednictvím InputDispatcher: pokud dotyk nebo stisk tlačítka není zpracován do 5 sekund, Android zobrazí dialog s nabídkou zavření nebo vyčkání na aplikaci.

Mechanismus ANR chraní uživatelský zážitek před zaseknutými aplikacemi. Android nedovoluje jedné aplikaci blokovat celý systém — na rozdíl od desktopových OS, mobilní platforma vynuceně omezuje dobu zpracování událostí. BroadcastReceiver má limit 10 sekund a foreground služba 20 sekund.

ANR NENÍ výjimkou v kódu — je to systémový mechanismus na úrovni Linuxových procesů. Android posílá procesu signál SIGQUIT, poté systém uloží zásobník volání všech vláken do souboru traces.txt. Vývojář dostává ANR nikoli jako catch-výjimku, ale jako hlášení po restartu aplikace. Na Androidu 11+ se objevilo API ApplicationExitInfo, které umožňuje programově získat příčinu ukončení procesu, včetně ANR — to zjednodušuje sběr statistik bez ručního parsování traces.txt.

Hlavní příčiny ANR

Pět kategorií operací stabilně vede k ANR v Android aplikacích. Každá z nich blokuje hlavní vlákno, bráníc systému zpracovávat vstupní události a překreslovat obrazovku.

Síťové požadavky na hlavním vlákně

Synchrónní HTTP požadavky provedené na UI vlákně — nejčastější příčina ANR u začínajících vývojářů. I rychlý požadavek na server může trvat 1–3 sekundy a při slabém připojení 30 sekund a více. Android výslovně zakazuje síťové operace na hlavním vlákně od API 11, vyhazujíc NetworkOnMainThreadException.

Používejte Coroutines nebo RxJava pro asynchronní volání. Korutiny s dispečerem Dispatchers.IO provádějí požadavek na pozadí a výsledek předávají na hlavní přes Dispatchers.Main. To zcela eliminuje blokování UI vlákna síťovými operacemi.

kotlin
fun fetchUserData() {
    CoroutineScope(Dispatchers.Main).launch {
        val result = withContext(Dispatchers.IO) {
            api.getUserData() // operace na pozadí
        }
        updateUI(result) // výsledek na hlavním vlákně
    }
}

Intenzivní výpočty na UI vlákně

Zpracování velkých datových polí, parsování JSON nebo XML, práce přímo s bitmapou na hlavním vlákně — druhá nejčastější příčina ANR. I 300 milisekund nepřetržité práce UI vlákna bez návratu do smyčky událostí způsobuje znatelné zpoždění vykreslování a hraniční hodnota 5 sekund je zaznamenána jako ANR.

WorkManager a služby na pozadí jsou určeny k přesunu těžkých výpočtů z hlavního vlákna. Používejte AsyncTask (zastaralý), ListenableFuture nebo Kotlin Flow k přenosu dat po částech bez blokování UI.

Blokování synchronizace a Deadlock

Deadlock nastane, když dvě vlákna drží zámky a čekají na sebe. Pokud je jedno z vláken hlavní, systém zaznamená ANR přesně po 5 sekundách. Thread.join(), CountDownLatch.await() a synchronized bloky volané z UI vlákna nesou riziko blokování.

Vyhněte se jakýmkoli blokujícím operacím na hlavním vlákně. Místo synchronized používejte ConcurrentHashMap, místo Thread.join() — korutiny s async/await. Toto pravidlo platí pro každý jazyk v Androidu: Java, Kotlin nebo C++ přes JNI.

Dlouhá práce BroadcastReceiver

BroadcastReceiver se standardně spouští na hlavním vlákně. Pokud je onReceive() zaneprázdněn více než 10 sekund, Android zobrazí ANR. Načítání dat z databáze nebo sítě uvnitř onReceive je zaručenou cestou k zaseknutí.

Použijte goAsync() uvnitř BroadcastReceiver pro přepnutí na vlákno na pozadí nebo registerReceiver s getBackgroundBroadcastReceiver(). To umožňuje zpracování událostí bez blokování UI.

ContentProvider a SQLite na hlavním vlákně

Těžké dotazy na ContentProvider nebo přímá práce s SQLite na UI vlákně — méně zřejmá, ale častá příčina ANR. Při migraci databáze nebo hromadném vkládání tisíců záznamů může doba provádění překročit 5sekundový limit.

Přeneste všechny operace s databází do vláken na pozadí přes Room s suspend funkcemi. Room automaticky kontroluje, že dotaz není prováděn na hlavním vlákně a při porušení vyhazuje výjimku.

Jak diagnostikovat ANR

Diagnostika ANR se liší od ladění běžných výjimek — nemůžete ANR zachytit v try-catch. Hlavním zdrojem informací je soubor traces.txt, který Android vytváří v okamžiku zamrznutí.

traces.txt obsahuje zásobník volání všech vláken aplikace v okamžiku ANR. Pro čtení souboru z reálného zařízení proveďte příkaz adb bugreport, který shromažďuje úplnou systémovou hlášku včetně všech ANR z poslední doby. Pro emulátor je soubor dostupný v /data/anr/traces.txt. Zásobník volání ukazuje, která metoda se prováděla na hlavním vlákně v okamžiku blokování.

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

Google Play Console poskytuje sekci ANR & Crash s agregovanými hláškami a frekvencemi chyb. Pro každý ANR je zobrazen zásobník volání a statistiky podle zařízení: model, verze Androidu, region. To umožňuje identifikovat ANR, které závisí na konkrétních zařízeních nebo verzích systému.

Android Studio od roku 2021 obsahuje ANR Watchdog v profilování. Automaticky zaznamenává dump vláken, pokud hlavní vlákno neodpovídá déle než prahový čas. Nástroj zobrazuje časovou osu událostí: jaké operace byly spuštěny, jaké metody byly prováděny a v jaké fázi došlo k blokování.

Jak předcházet ANR

Prevence ANR je postavena na jednom základním pravidle: hlavní vlákno by mělo zpracovávat pouze události UI. Jakákoli operace trvající déle než 16 milisekund (čas jednoho snímku) by měla být provedena na vlákně na pozadí.

StrictMode — automatická kontrola

StrictMode — vestavěný nástroj Androidu pro detekci potenciálních ANR ve fázi vývoje. Zapněte jej v Application.onCreate() s příznaky pro diskové a síťové operace. Při porušení StrictMode vyhodí výjimku nebo zapíše do logcat.

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

Asynchronní vzory: Coroutines a RxJava

Kotlin Coroutines — standardní způsob asynchronní práce v moderních Android aplikacích. Základní princip: I/O operace se provádějí na Dispatchers.IO, výsledek se předává na Dispatchers.Main pro aktualizaci UI. Pro Flow scénáře použijte Dispatchers.Default pro CPU náročné úlohy.

RxJava zůstává populární v legacy projektech. subscribeOn(Schedulers.io()) a observeOn(AndroidSchedulers.mainThread()) — minimální sada pro prevenci ANR. Stejné pravidlo: žádný Observable ani Flowable by neměly emitovat data z hlavního vlákna.

Monitorování v produkci

Firebase Crashlytics od verze SDK 18.4.0 podporuje monitorování ANR hned z krabice. Pro Android 11+ Crashlytics používá systémové API ApplicationExitInfo, které poskytuje přesnou příčinu ukončení: ANR, Crash nebo zabití systémem. Zapněte vlastní klíče s parametry obrazovky a stavu pro kontextovou analýzu.

Nástroje pro detekci ANR

Pět nástrojů pokrývá všechny fáze práce s ANR: od ladění na pracovní stanici až po monitorování v produkci. Každý nástroj řeší svůj úkol a poskytuje data pro různé scénáře.

NástrojÚčelFormát dat
StrictModeDetekce ve fázi vývojeLogcat / Exception
ANR Watchdog (Android Studio)Sledování v reálném časeThread dump + timeline
Google Play ConsoleAgregované statistikyANR rate + stack traces
Firebase CrashlyticsProdukční monitorováníApplicationExitInfo
adb bugreportÚplná systémová hláškatraces.txt + logcat + dmesg

Každý nástroj má své místo: StrictMode chytá zřejmá porušení v raných fázích, Crashlytics ukazuje skutečnou frekvenci ANR u uživatelů a adb bugreport poskytuje nejúplnější obrázek pro složité případy. Kombinujte je pro úplné pokrytí.

Firebase Performance Monitoring

Firebase Performance sleduje dobu odezvy UI vlákna a automaticky vytváří trasování pro podezřele dlouhé operace. Pokud je hlavní vlákno blokováno více než 500 ms, Performance zaznamená vlastní trasování s názvem metody viníka. To umožňuje detekovat scénáře ANR bez účasti uživatele a dříve, než se stanou kritickými.

Integrace s Firebase Crashlytics dává úplný obrázek: Performance ukazuje zpomalení před ANR a Crashlytics samotný fakt zamrznutí. Nastavte výstrahy v Firebase Console na událost ANR rate nad 0,1 % a budete dostávat upozornění na nové problémy dříve, než přijdou hromadné stížnosti uživatelů.

Časté dotazy

Čím se ANR liší od Crash?

ANR — je zamrznutí, při kterém aplikace neodpovídá, ale zůstává v paměti. Crash — úplné nouzové ukončení s opuštěním procesu. ANR lze přežít, pokud systém nebo uživatel počká na odpověď, zatímco Crash vždy ukončí aplikaci.

Lze ANR zachytit pomocí try-catch?

Ne. ANR není výjimkou Java/Kotlin, ale systémovým signálem na úrovni procesů (SIGQUIT). Vývojář jej nemůže zpracovat v kódu aplikace. Jediný způsob, jak reagovat na ANR, je analyzovat hlášení po restartu.

Proč se ANR objevuje na některých zařízeních, ale na jiných ne?

Výkon zařízení, verze Androidu, zatížení CPU a počet procesů na pozadí ovlivňují pravděpodobnost ANR. Na slabších zařízeních může stejná operace trvat 2–3krát déle a překročit 5sekundový limit.

Jaký je časový limit BroadcastReceiver před ANR?

10 sekund pro běžný BroadcastReceiver v onReceive(). Pro foreground služby je limit 20 sekund a pro ContentProvider neexistuje explicitní limit, ale blokování hlavního vlákna déle než 5 sekund stejně způsobí ANR.

Co dělat, když se ANR vyskytuje zřídka a nelze jej reprodukovat?

Zapněte StrictMode ve všech debug sestaveních, přidejte monitorování přes Firebase Crashlytics a používejte adb bugreport, když ANR nastane. Nepravidelné ANR často souvisí s race condition nebo specifickými stavy sítě.

Shrnutí

  • ANR — systémový mechanismus Androidu aktivovaný při blokování hlavního vlákna déle než 5 sekund
  • Hlavní vlákno by se mělo zabývat pouze UI — všechny ostatní operace se přesouvají na vlákna na pozadí
  • Diagnostika ANR probíhá pomocí traces.txt, Google Play Console a Firebase Crashlytics
  • StrictMode detekuje potenciální ANR ve fázi vývoje bez spuštění na reálném zařízení
  • Coroutines s Dispatchers.IO — standardní způsob asynchronní práce v moderních Android projektech
  • BroadcastReceiver vyžaduje goAsync() nebo registrátor na pozadí pro práci delší než 10 sekund
  • ANR v produkci je monitorován přes Crashlytics a vestavěné API ApplicationExitInfo na Androidu 11 a vyšších

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é