ANR in Android-ontwikkeling — wat het is, oorzaken en oplossingen

Auteur: IT Sectr Gepubliceerd: 2026-03-28 Leestijd: 9 min

ANR (Application Not Responding) — is een systeemmelding van Android die verschijnt wanneer een app langer dan 5 seconden niet reageert op gebruikersinvoer. Volgens Android Developers is de belangrijkste oorzaak lange bewerkingen op de hoofdthread die de verwerking van aanrakingen en het renderen van de interface blokkeren. Begrip van ANR-mechanismen is noodzakelijk voor elke Android-ontwikkelaar om responsieve apps te maken.

Belangrijkste punten

  • ANR — systeemwaarschuwing van Android bij vastlopen van de app langer dan 5 seconden
  • Hoofdthread (UI-thread) — de enige plek waar blokkering leidt tot ANR
  • InputDispatcher — systeemcomponent dat invoervertraging registreert en ANR initieert
  • traces.txt — sleutelbestand voor diagnose van de oorzaak van vastlopen op het apparaat
  • StrictMode — ingebouwde Android-tool voor detectie van lange bewerkingen op de UI-thread

Wat is ANR

ANR (Application Not Responding) — is een dialoogvenster van het Android-besturingssysteem dat verschijnt wanneer een app stopt met reageren op gebruikersinvoer. Het systeem houdt de verwerkingstijd van gebeurtenissen bij via InputDispatcher: als een aanraking of knopdruk niet binnen 5 seconden wordt verwerkt, toont Android een dialoog met de optie om de app te sluiten of te wachten.

Het ANR-mechanisme beschermt de gebruikerservaring tegen vastgelopen apps. Android staat niet toe dat één app het hele systeem blokkeert — in tegenstelling tot desktopbesturingssystemen beperkt het mobiele platform de verwerkingstijd van gebeurtenissen afdwingbaar. BroadcastReceiver heeft een limiet van 10 seconden en een foreground-service van 20 seconden.

ANR is GEEN uitzondering in code — het is een systeemmechanisme op het niveau van Linux-processen. Android stuurt een SIGQUIT-signaal naar het proces, waarna het systeem de callstack van alle threads opslaat in het bestand traces.txt. De ontwikkelaar ontvangt ANR niet als een catch-uitzondering, maar als een rapport na het opnieuw opstarten van de app. Op Android 11+ is de API ApplicationExitInfo verschenen waarmee programmatisch de oorzaak van procesbeëindiging kan worden verkregen, inclusief ANR — dit vereenvoudigt het verzamelen van statistieken zonder handmatig parsen van traces.txt.

Belangrijkste oorzaken van ANR

Vijf categorieën bewerkingen leiden consistent tot ANR in Android-apps. Elk ervan blokkeert de hoofdthread, waardoor het systeem geen invoergebeurtenissen kan verwerken en het scherm niet opnieuw kan tekenen.

Netwerkverzoeken op de hoofdthread

Synchrone HTTP-verzoeken uitgevoerd op de UI-thread — de meest voorkomende oorzaak van ANR bij beginnende ontwikkelaars. Zelfs een snel verzoek naar de server kan 1–3 seconden duren, en bij een slechte verbinding 30 seconden of meer. Android verbiedt expliciet netwerkbewerkingen op de hoofdthread vanaf API 11 en gooit NetworkOnMainThreadException.

Gebruik Coroutines of RxJava voor asynchrone aanroepen. Coroutines met de dispatcher Dispatchers.IO voeren het verzoek uit op de achtergrondthread en geven het resultaat door aan de hoofdthread via Dispatchers.Main. Dit elimineert volledig het blokkeren van de UI-thread door netwerkbewerkingen.

kotlin
fun fetchUserData() {
    CoroutineScope(Dispatchers.Main).launch {
        val result = withContext(Dispatchers.IO) {
            api.getUserData() // achtergrondbewerking
        }
        updateUI(result) // resultaat op de hoofdthread
    }
}

Intensieve berekeningen op de UI-thread

Verwerking van grote gegevensarrays, parseren van JSON of XML, direct werken met bitmap op de hoofdthread — de tweede meest voorkomende oorzaak van ANR. Zelfs 300 milliseconden ononderbroken werk van de UI-thread zonder terugkeer naar de gebeurtenislus veroorzaakt merkbare vertraging in rendering, en de grenswaarde van 5 seconden wordt geregistreerd als ANR.

WorkManager en achtergrondservices zijn ontworpen om zware berekeningen van de hoofdthread te verplaatsen. Gebruik AsyncTask (verouderd), ListenableFuture of Kotlin Flow om gegevens in porties te verzenden zonder de UI te blokkeren.

Synchronisatieblokkeringen en Deadlock

Deadlock treedt op wanneer twee threads vergrendelingen vasthouden en op elkaar wachten. Als een van de threads de hoofdthread is, registreert het systeem ANR exact na 5 seconden. Thread.join(), CountDownLatch.await() en synchronized-blokken aangeroepen vanaf de UI-thread brengen het risico van blokkering met zich mee.

Vermijd alle blokkerende bewerkingen op de hoofdthread. Gebruik in plaats van synchronized ConcurrentHashMap, in plaats van Thread.join() — coroutines met async/await. Deze regel geldt voor elke taal in Android: Java, Kotlin of C++ via JNI.

Langdurig werk van BroadcastReceiver

BroadcastReceiver wordt standaard uitgevoerd op de hoofdthread. Als onReceive() langer dan 10 seconden bezig is, toont Android ANR. Het laden van gegevens uit de database of het netwerk binnen onReceive is een gegarandeerde weg naar vastlopen.

Gebruik goAsync() binnen BroadcastReceiver om over te schakelen naar de achtergrondthread of registerReceiver met getBackgroundBroadcastReceiver(). Dit maakt verwerking van gebeurtenissen mogelijk zonder de UI te blokkeren.

ContentProvider en SQLite op de hoofdthread

Zware querys naar ContentProvider of direct werken met SQLite op de UI-thread — een minder voor de hand liggende maar veelvoorkomende oorzaak van ANR. Bij databasemigratie of bulk-invoeging van duizenden records kan de uitvoeringstijd de limiet van 5 seconden overschrijden.

Verplaats alle database-bewerkingen naar achtergrondthreads via Room met suspend-functies. Room controleert automatisch of de query niet op de hoofdthread wordt uitgevoerd en gooit een uitzondering bij overtreding.

Hoe ANR diagnosticeren

Diagnose van ANR verschilt van het debuggen van gewone uitzonderingen — u kunt ANR niet vangen in een try-catch. De belangrijkste informatiebron is het bestand traces.txt dat Android aanmaakt op het moment van vastlopen.

traces.txt bevat de callstack van alle threads van de app op het moment van ANR. Om het bestand van een echt apparaat te lezen, voert u het commando adb bugreport uit dat een compleet systeemrapport verzamelt, inclusief alle recente ANRs. Voor de emulator is het bestand beschikbaar in /data/anr/traces.txt. De callstack laat zien welke methode op de hoofdthread werd uitgevoerd op het moment van blokkering.

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

Google Play Console biedt de sectie ANR & Crash met samengevoegde rapporten en foutfrequenties. Voor elke ANR wordt de callstack en statistieken per apparaat getoond: model, Android-versie, regio. Dit maakt het mogelijk om ANRs te identificeren die afhankelijk zijn van specifieke apparaten of systeemversies.

Android Studio bevat sinds 2021 ANR Watchdog in de profiler. Het registreert automatisch een dump van threads als de hoofdthread langer dan de drempelwaarde niet reageert. De tool toont een tijdlijn van gebeurtenissen: welke bewerkingen zijn gestart, welke methoden zijn uitgevoerd en in welke fase de blokkering plaatsvond.

Hoe ANR voorkomen

Preventie van ANR is gebaseerd op één fundamentele regel: de hoofdthread mag alleen UI-gebeurtenissen verwerken. Elke bewerking die langer duurt dan 16 milliseconden (de tijd van één frame) moet worden uitgevoerd op de achtergrondthread.

StrictMode — automatische controle

StrictMode — ingebouwde Android-tool voor detectie van potentiële ANRs in de ontwikkelingsfase. Schakel het in in Application.onCreate() met vlaggen voor schijf- en netwerkbewerkingen. Bij overtreding gooit StrictMode een uitzondering of schrijft naar logcat.

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

Asynchrone patronen: Coroutines en RxJava

Kotlin Coroutines — de standaard manier van asynchroon werken in moderne Android-apps. Het basisprincipe: invoer-uitvoerbewerkingen worden uitgevoerd op Dispatchers.IO, het resultaat wordt doorgegeven aan Dispatchers.Main voor UI-updates. Gebruik voor Flow-scenario’s Dispatchers.Default voor CPU-intensieve taken.

RxJava blijft populair in legacy-projecten. subscribeOn(Schedulers.io()) en observeOn(AndroidSchedulers.mainThread()) — minimale set voor preventie van ANR. Dezelfde regel: geen Observable of Flowable mag gegevens emitteren vanaf de hoofdthread.

Monitoring in productie

Firebase Crashlytics ondersteunt vanaf SDK-versie 18.4.0 ANR-monitoring uit de doos. Voor Android 11+ gebruikt Crashlytics de systeem-API ApplicationExitInfo die de exacte oorzaak van beëindiging levert: ANR, Crash of doden door het systeem. Schakel aangepaste sleutels in met scherm- en statusparameters voor contextuele analyse.

Tools voor ANR-detectie

Vijf tools dekken alle fasen van werken met ANR: van debuggen op de werkstation tot monitoring in productie. Elke tool lost zijn taak op en levert gegevens voor verschillende scenario’s.

ToolDoelGegevensformaat
StrictModeDetectie in ontwikkelingsfaseLogcat / Exception
ANR Watchdog (Android Studio)Realtime traceringThread dump + timeline
Google Play ConsoleSamengevoegde statistiekANR rate + stack traces
Firebase CrashlyticsProductiemonitoringApplicationExitInfo
adb bugreportVolledig systeemrapporttraces.txt + logcat + dmesg

Elke tool heeft zijn eigen niche: StrictMode vangt duidelijke overtredingen in vroege stadia, Crashlytics toont de werkelijke frequentie van ANR bij gebruikers, en adb bugreport geeft het meest complete beeld voor complexe gevallen. Combineer ze voor volledige dekking.

Firebase Performance Monitoring

Firebase Performance volgt de responstijd van de UI-thread en maakt automatisch traces aan voor verdacht lange bewerkingen. Als de hoofdthread langer dan 500 ms wordt geblokkeerd, registreert Performance een custom trace met de naam van de veroorzakende methode. Dit maakt detectie van ANR-scenario’s mogelijk zonder gebruikersbetrokkenheid en voordat ze kritiek worden.

Integratie met Firebase Crashlytics geeft een compleet beeld: Performance toont vertragingen voor ANR, en Crashlytics — het feit van vastlopen zelf. Configureer waarschuwingen in Firebase Console voor ANR rate boven 0,1% en u ontvangt meldingen over nieuwe problemen voordat er massale gebruikersklachten komen.

Veelgestelde vragen

Wat is het verschil tussen ANR en Crash?

ANR — is een vastloper waarbij de app niet reageert maar in het geheugen blijft. Crash — volledige noodstop met afsluiting van het proces. ANR kan worden overleefd als het systeem of de gebruiker op antwoord wacht, terwijl Crash de app altijd beëindigt.

Kan ANR worden gevangen met try-catch?

Nee. ANR is geen Java/Kotlin-uitzondering, maar een systeemsignaal op processniveau (SIGQUIT). De ontwikkelaar kan het niet verwerken in de app-code. De enige manier om op ANR te reageren is het analyseren van rapporten na herstart.

Waarom verschijnt ANR op sommige apparaten maar niet op andere?

Prestaties van het apparaat, Android-versie, CPU-belasting en aantal achtergrondprocessen beïnvloeden de kans op ANR. Op zwakkere apparaten kan dezelfde bewerking 2–3 keer langer duren en de limiet van 5 seconden overschrijden.

Wat is de tijdslimiet van BroadcastReceiver voor ANR?

10 seconden voor gewone BroadcastReceiver in onReceive(). Voor foreground-services is de limiet 20 seconden, en voor ContentProvider is er geen expliciete limiet, maar blokkering van de hoofdthread langer dan 5 seconden veroorzaakt nog steeds ANR.

Wat te doen als ANR zelden voorkomt en niet reproduceerbaar is?

Schakel StrictMode in alle debug-builds in, voeg monitoring toe via Firebase Crashlytics en gebruik adb bugreport wanneer ANR optreedt. Onregelmatige ANRs zijn vaak gerelateerd aan race conditions of specifieke netwerkomstandigheden.

Samenvatting

  • ANR — systeemmechanisme van Android dat wordt geactiveerd bij blokkering van de hoofdthread langer dan 5 seconden
  • Hoofdthread moet alleen met UI bezig zijn — alle andere bewerkingen worden naar achtergrondthreads verplaatst
  • Diagnose van ANR gebeurt via traces.txt, Google Play Console en Firebase Crashlytics
  • StrictMode detecteert potentiële ANRs in de ontwikkelingsfase zonder uitvoering op een echt apparaat
  • Coroutines met Dispatchers.IO — de standaard manier van asynchroon werken in moderne Android-projecten
  • BroadcastReceiver vereist goAsync() of een achtergrondregistrator voor werk langer dan 10 seconden
  • ANR in productie wordt gemonitord via Crashlytics en de ingebouwde API ApplicationExitInfo op Android 11 en hoger

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook