ANR az Android fejlesztésben — mi ez, okai és javítási módszerek

Szerző: IT Sectr Megjelenés: 2026-03-28 Olvasási idő: 9 perc

ANR (Application Not Responding) — ez egy Android rendszerüzenet, amely akkor jelenik meg, amikor az alkalmazás több mint 5 másodpercig nem válaszol a felhasználói bevitelre. A Android Developers szerint a fő ok a fő szálon végzett hosszú műveletek, amelyek blokkolják az érintések feldolgozását és a felület megjelenítését. Az ANR mechanizmusainak megértése minden Android-fejlesztő számára szükséges a reszponzív alkalmazások létrehozásához.

Főbb pontok

  • ANR — Android rendszer figyelmeztetés, amikor az alkalmazás 5 másodperc nál tovább lefagy
  • Fő szál (UI szál) — az egyetlen hely, ahol a blokkolás ANR-hez vezet
  • InputDispatcher — rendszerkomponens, amely rögzíti a beviteli késleltetést és elindítja az ANR-t
  • traces.txt — kulcsfontosságú fájl a lefagyás okának diagnosztizálásához az eszközön
  • StrictMode — beépített Android eszköz a hosszú műveletek észlelésére az UI szálon

Mi az ANR

ANR (Application Not Responding) — ez az Android operációs rendszer párbeszédablaka, amely akkor jelenik meg, amikor az alkalmazás nem válaszol a felhasználói bevitelre. A rendszer az InputDispatcheren keresztül követi nyomon az események feldolgozási idejét: ha egy érintés vagy gombnyomás nem kerül feldolgozásra 5 másodpercen belül, az Android megjelenít egy párbeszédablakot az alkalmazás bezárásának vagy várakozásnak a lehetőségével.

Az ANR mechanizmus védi a felhasználói élményt a lefagyott alkalmazásoktól. Az Android nem engedi, hogy egyetlen alkalmazás blokkolja az egész rendszert — a Desktop operációs rendszerekkel ellentétben a mobil platform kényszerítően korlátozza az események feldolgozási idejét. A BroadcastReceiver 10 másodperces, az foreground szolgáltatás pedig 20 másodperces korláttal rendelkezik.

Az ANR NEM kivétel a kódban — ez egy rendszermechanizmus a Linux folyamatok szintjén. Az Android SIGQUIT jelet küld a folyamatnak, ezután a rendszer az összes szál hívási vermét elmenti a traces.txt fájlba. A fejlesztő az ANR-t nem catch-kivételként, hanem jelentésként kapja az alkalmazás újraindítása után. Az Android 11+ rendszerben megjelent az ApplicationExitInfo API, amely lehetővé teszi a folyamat megszakításának okának programozott lekérését, beleértve az ANR-t — ez leegyszerűsíti a statisztikák gyűjtését a traces.txt manuális elemzése nélkül.

Az ANR fő okai

Öt kategória művelet vezet stabilan ANR-hez az Android alkalmazásokban. Mindegyik blokkolja a fő szálat, megakadályozva a rendszert a bemeneti események feldolgozásában és a képernyő újrarajzolásában.

Hálózati kérések a fő szálon

Szinkron HTTP kérések az UI szálon végrehajtva — a leggyakoribb ANR ok a kezdő fejlesztőknél. Még egy gyors kérés a szerverhez is tarthat 1–3 másodpercig, gyenge kapcsolatnál pedig 30 másodpercig vagy többig. Az Android API 11-től kezdve kifejezetten tiltja a hálózati műveleteket a fő szálon, NetworkOnMainThreadException kivételt dobva.

Használjon Coroutines-t vagy RxJava-t aszinkron hívásokhoz. A Dispatchers.IO diszpáccserrel rendelkező korutinok a háttérszálon hajtják végre a kérést, az eredményt pedig a Dispatchers.Main-en keresztül juttatják el a fő szálra. Ez teljesen kiküszöböli az UI szál hálózati műveletek általi blokkolását.

kotlin
fun fetchUserData() {
    CoroutineScope(Dispatchers.Main).launch {
        val result = withContext(Dispatchers.IO) {
            api.getUserData() // háttérművelet
        }
        updateUI(result) // eredmény a fő szálon
    }
}

Intenzív számítások az UI szálon

Nagy adattömbök feldolgozása, JSON vagy XML elemzése, képek közvetlen kezelése a fő szálon — a második leggyakoribb ANR ok. Már 300 ezredmásodpercnyi megszakítás nélkül működés az UI szálon az eseményhurokba való visszatérés nélkül észrevehető késői megjelenítést okoz, az 5 másodperces határérték pedig ANR-ként kerül rögzítésre.

A WorkManager és a háttérszolgáltatások a nehéz számítások fő szálról történő áthelyezésére szolgálnak. Használja az AsyncTask (elavult), ListenableFuture vagy Kotlin Flow alkalmazást az adatok részletekben történő továbbításához, az UI blokkolása nélkül.

Szinkronizációs zárak és Deadlock

Deadlock akkor fordul elő, amikor két szál zárakat tart és egymásra vár. Ha az egyik szál a fő szál, a rendszer pontosan 5 másodperc után rögzíti az ANR-t. Az UI szálról meghívott Thread.join(), CountDownLatch.await() és synchronized blokkok zárolási kockázatot hordoznak.

Kerüljön minden blokkoló műveletet a fő szálon. A synchronized helyett használjon ConcurrentHashMap-t, a Thread.join() helyett — korutinokat async/await-tel. Ez a szabály minden Android nyelven érvényes: Java, Kotlin vagy C++ JNI-n keresztül.

BroadcastReceiver hosszú működése

BroadcastReceiver alapértelmezésben a fő szálon fut. Ha az onReceive() több mint 10 másodpercig elfoglalt, az Android ANR-t jelenít meg. Adatok betöltése az adatbázisból vagy hálózatról az onReceive-on belül garantált út a lefagyáshoz.

Használja a goAsync() függvényt a BroadcastReceiver-en belül a háttérszálra váltáshoz, vagy a registerReceiver-t a getBackgroundBroadcastReceiver()-rel. Ez lehetővé teszi az események feldolgozását az UI blokkolása nélkül.

ContentProvider és SQLite a fő szálon

Nehéz lekérdezések a ContentProvider-hez vagy közvetlen munka az SQLite-tal az UI szálon — kevésbé nyilvánvaló, de gyakori ANR ok. Adatbázis migráció vagy ezrek tömeges beszúrása során a végrehajtási idő meghaladhatja az 5 másodperces korlátot.

Helyezze át az összes adatbázis műveletet a háttérszálakra a Room-on keresztül suspend függvényekkel. A Room automatikusan ellenőrzi, hogy a lekérdezés nem a fő szálon fut-e, és megszegés esetén kivételt dob.

Hogyan diagnosztizáljuk az ANR-t

Az ANR diagnosztizálása eltér a szokásos kivételek hibakeresésétől — az ANR-t nem lehet try-catch-ben elkapni. A fő információforrás a traces.txt fájl, amelyet az Android a lefagyás pillanatában hoz létre.

traces.txt tartalmazza az alkalmazás összes szálának hívási vermét az ANR pillanatában. A fájl valós eszközről történő olvasásához hajtsa végre az adb bugreport parancsot, amely teljes rendszerjelentést gyűjt, beleértve az összes közelmúltbeli ANR-t. Az emulátor esetében a fájl a /data/anr/traces.txt címen érhető el. A hívási verem megmutatja, melyik módszer futott a fő szálon a blokkolás pillanatában.

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

Google Play Console ANR & Crash szekciót biztosít összesített jelentésekkel és hibagyakoriságokkal. Minden ANR-hoz megjelenik a hívási verem és eszközönkénti statisztika: modell, Android verzió, régió. Ez lehetővé teszi azon ANR-k azonosítását, amelyek adott eszközöktől vagy rendszerváltozatoktól függnek.

Az Android Studio 2021 óta tartalmazza az ANR Watchdog-ot a profilozóban. Automatikusan rögzíti a szálak dumpját, ha a fő szál nem válaszol a küszöbértéknél tovább. Az eszköz az események idővonalát mutatja: mely műveletek indultak el, mely módszerek futottak és melyik szakaszban történt a blokkolás.

Hogyan előzzük meg az ANR-t

Az ANR megelőzése egy alapvető szabályon alapul: a fő szál csak UI eseményeket dolgozhat fel. Minden 16 ezredmásodpercnel (egy képkocka ideje) tovább tartó műveletet a háttérszálon kell végrehajtani.

StrictMode — automatikus ellenőrzés

StrictMode — beépített Android eszköz a potenciális ANR-k észlelésére a fejlesztési fázisban. Kapcsolja be az Application.onCreate()-ban lemez- és hálózati műveletek jelzőivel. Megszegés esetén a StrictMode kivételt dob vagy a logcat-be ír.

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

Aszinkron minták: Coroutines és RxJava

Kotlin Coroutines — az aszinkron munka szabványos módja a modern Android alkalmazásokban. Alapelv: a be- és kimeneti műveletek a Dispatchers.IO-n futnak, az eredmény a Dispatchers.Main-re kerül az UI frissítéséhez. Flow forgatókönyvekhez használja a Dispatchers.Default-ot CPU-igényes feladatokhoz.

RxJava népszerű marad a régebbi projektekben. a subscribeOn(Schedulers.io()) és observeOn(AndroidSchedulers.mainThread()) — minimális készlet az ANR megelőzéséhez. Ugyanaz a szabály: egy Observable vagy Flowable sem bocsáthat ki adatokat a fő szálról.

Monitorozás éles környezetben

Firebase Crashlytics az SDK 18.4.0 verziótól dobozból támogatja az ANR monitorozást. Android 11+ rendszeren a Crashlytics a rendszer ApplicationExitInfo API-ját használja, amely pontos megszakítási okot ad: ANR, Crash vagy rendszer általi megszakítás. Kapcsolja be az egyéni kulcsokat képernyő- és állapotparaméterekkel a kontextuális elemzéshez.

ANR észlelési eszközök

Öt eszköz fedi le az ANR-rel való munka összes szakaszát: a munkaállomáson történő hibakereséstől az éles környezeti monitorozásig. Minden eszköz megoldja a saját feladatát és adatokat szolgáltat különböző forgatókönyvekhez.

EszközCélAdatformátum
StrictModeÉszlelés fejlesztési fázisbanLogcat / Exception
ANR Watchdog (Android Studio)Valós idejű követésThread dump + timeline
Google Play ConsoleÖsszesített statisztikaANR rate + stack traces
Firebase CrashlyticsÉles monitorozásApplicationExitInfo
adb bugreportTeljes rendszerjelentéstraces.txt + logcat + dmesg

Minden eszköznek megvan a maga rése: a StrictMode a korai szakaszban kapja el a nyilvánvaló megszegéseket, a Crashlytics mutatja az ANR valós gyakoriságát a felhasználóknál, az adb bugreport pedig a legteljesebb képet adja az összetett esetekhez. Kombinálja őket a teljes lefedettség érdekében.

Firebase Performance Monitoring

Firebase Performance nyomon követi az UI szál válaszidejét és automatikusan nyomokat hoz létre a gyanísan hosszú műveletekhez. Ha a fő szál több mint 500 ms-ig blokkolódik, a Performance rögzít egy egyéni nyomot a vétkes módszer nevével. Ez lehetővé teszi az ANR forgatókönyvek észlelését felhasználói részvétel nélkül, mielőtt azok kritikussá válnának.

Az Firebase Crashlytics integráció teljes képet ad: a Performance mutatja az ANR előtti lassulásokat, a Crashlytics pedig magát a lefagyás tényét. Állítson be riasztásokat a Firebase Console-ban a 0,1% feletti ANR arány eseményre, és értesítést kap az új problémákról, mielőtt tömeges felhasználói panaszok érkeznének.

Gyakran ismételt kérdések

Miben különbözik az ANR a Crash-től?

ANR — olyan lefagyás, amelynél az alkalmazás nem válaszol, de a memóriában marad. Crash — teljes vészhelyzeti befejezés a folyamatból való kilépéssel. Az ANR túlélhető, ha a rendszer vagy a felhasználó megvárja a választ, a Crash azonban mindig befejezi az alkalmazást.

Elkapható az ANR try-catch segítségével?

Nem. Az ANR nem Java/Kotlin kivétel, hanem rendszerjel a folyamatok szintjén (SIGQUIT). A fejlesztő nem tudja feldolgozni az alkalmazás kódjában. Az ANR-re való reagálás egyetlen módja a jelentések elemzése az újraindítás után.

Miért jelenik meg ANR egyes eszközökön, másokon pedig nem?

Az eszköz teljesítménye, Android verziója, CPU terhelése és a háttérfolyamatok száma befolyásolja az ANR valószínűségét. Gyengébb eszközökön ugyanaz a művelet 2–3-szor tovább tarthat, így meghaladva az 5 másodperces korlátot.

Mennyi a BroadcastReceiver időkorlátja ANR előtt?

10 másodperc a szokásos BroadcastReceiver számára az onReceive()-ben. Foreground szolgáltatásoknál a korlát 20 másodperc, a ContentProvider esetében pedig nincs kifejezett korlát, de a fő szál 5 másodperc túlí blokkolása továbbra is ANR-t okoz.

Mit tegyünk, ha az ANR ritkán fordul elő és nem reprodukálható?

Kapcsolja be a StrictMode-ot az összes debug buildben, adjon hozzá monitorozást Firebase Crashlytics-en keresztül, és használja az adb bugreport-ot, amikor ANR történik. A rendszertelen ANR-k gyakran versenyhelyzetekhez (race condition) vagy speciális hálózati állapotokhoz kapcsolódnak.

Összefoglaló

  • ANR — Android rendszermechanizmus, amely a fő szál 5 másodpercet meghaladó blokkolásakor aktiválódik
  • Fő szál csak UI-val foglalkozhat — minden más művelet a háttérszálakra kerül áthelyezésre
  • ANR diagnosztizálása traces.txt, Google Play Console és Firebase Crashlytics segítségével történik
  • StrictMode észleli a potenciális ANR-kat a fejlesztési fázisban, valós eszközön történő futtatás nélkül
  • Coroutines Dispatchers.IO-val — az aszinkron munka szabványos módja a modern Android projektekben
  • BroadcastReceiver goAsync()-t vagy háttérregisztrálót igényel a 10 másodpercet meghaladó munkához
  • ANR éles környezetben a Crashlytics és a beépített ApplicationExitInfo API segítségével figyelhető Android 11 és felett

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is