ANR (Application Not Responding) — är ett systemmeddelande i Android som visas när appen slutar svara på användarens inmatning i mer än 5 sekunder. Enligt Android Developers är huvudorsaken långa operationer på huvudtråden som blockerar beröringshantering och gränssnittsrendering. Förståelse av ANR-mekanismer är nödvändig för varje Android-utvecklare för att skapa responsiva appar.
Huvudpunkter
ANR (Application Not Responding) — är en dialogruta i operativsystemet Android som visas när appen slutar svara på användarens inmatning. Systemet övervakar behandlingstiden för händelser via InputDispatcher: om en beröring eller knapptryckning inte bearbetas inom 5 sekunder visar Android en dialogruta med förslag att stänga eller vänta på appen.
ANR-mekanismen skyddar användarupplevelsen från frusna appar. Android tillåter inte en app att blockera hela systemet — till skillnad från Desktop-OS begränsar den mobila plattformen tvångsmässigt händelsebehandlingstiden. BroadcastReceiver har en gräns på 10 sekunder och foreground-tjänsten 20 sekunder.
ANR är INTE ett undantag i koden — det är en systemmekanism på Linux-processnivå. Android skickar signalen SIGQUIT till processen, varefter systemet sparar anropsstacken för alla trådar i filen traces.txt. Utvecklaren får ANR inte som ett catch-undantag utan som en rapport efter omstart av appen. Från Android 11+ finns API ApplicationExitInfo som gör det möjligt att programmatiskt få orsaken till processavslutning, inklusive ANR — detta förenklar statistikinsamling utan manuell tolkning av traces.txt.
Fem kategorier av operationer leder stadigt till ANR i Android-appar. Var och en blockerar huvudtråden och hindrar systemet från att behandla inmatningshändelser och uppdatera skärmen.
Synkrona HTTP-förfrågningar som körs på UI-tråden — den vanligaste orsaken till ANR hos nybörjare. Även en snabb förfrågan till servern kan ta 1–3 sekunder, och vid dålig anslutning — 30 sekunder eller mer. Android förbjuder uttryckligen nätverksoperationer på huvudtråden från och med API 11 och kastar NetworkOnMainThreadException.
Använd Coroutines eller RxJava för asynkrona anrop. Korutiner med dispatchern Dispatchers.IO utför förfrågan i en bakgrundstråd och skickar resultatet till huvudtråden via Dispatchers.Main. Detta eliminerar helt blockering av UI-tråden från nätverksoperationer.
fun fetchUserData() {
CoroutineScope(Dispatchers.Main).launch {
val result = withContext(Dispatchers.IO) {
api.getUserData() // bakgrundsoperation
}
updateUI(result) // resultat på huvudtråden
}
}
Bearbetning av stora datamängder, tolkning av JSON eller XML, arbete med bitmap direkt på huvudtråden — den näst vanligaste orsaken till ANR. Även 300 millisekunders kontinuerligt arbete på UI-tråden utan att återgå till händelseloopen orsakar märkbar renderingsfördröjning, och gränsvärdet på 5 sekunder registreras som ANR.
WorkManager och bakgrundstjänster är avsedda för att flytta tunga beräkningar från huvudtråden. Använd AsyncTask (föråldrat), ListenableFuture eller Kotlin Flow för att överföra data i delar utan att blockera UI.
Deadlock uppstår när två trådar håller lås och väntar på varandra. Om en av trådarna är huvudtråden registrerar systemet ANR efter exakt 5 sekunder. Thread.join(), CountDownLatch.await() och synchronized-block som anropas från UI-tråden innebär risk för blockering.
Undvik alla blockerande operationer på huvudtråden. Använd ConcurrentHashMap istället för synchronized, och korutiner med async/await istället för Thread.join(). Denna regel gäller för alla språk i Android: Java, Kotlin eller C++ via JNI.
BroadcastReceiver körs som standard på huvudtråden. Om onReceive() är upptagen i mer än 10 sekunder visar Android ANR. Att ladda data från databasen eller nätverket inuti onReceive — en garanterad väg till frysning.
Använd goAsync() inuti BroadcastReceiver för att växla till en bakgrundstråd, eller registerReceiver med getBackgroundBroadcastReceiver(). Detta gör det möjligt att bearbeta händelser utan att blockera UI.
Tunga förfrågningar till ContentProvider eller direkt arbete med SQLite på UI-tråden — en mindre uppenbar men vanlig orsak till ANR. Vid databasmigrering eller massinfogning av tusentals poster kan exekveringstiden överstiga 5-sekundersgränsen.
Flytta alla databasoperationer till bakgrundstrådar via Room med suspend-funktioner. Room kontrollerar automatiskt att förfrågan inte körs på huvudtråden och kastar ett undantag vid överträdelse.
Diagnostik av ANR skiljer sig från felsökning av vanliga undantag — du kan inte fånga ANR i en try-catch. Huvudkällan till information är filen traces.txt som Android skapar i frysmomentet.
traces.txt innehåller anropsstacken för alla appens trådar vid ANR-tillfället. För att läsa filen från en verklig enhet, kör kommandot adb bugreport som samlar en fullständig systemrapport inklusive alla ANR från den senaste tiden. För emulatorn är filen tillgänglig på /data/anr/traces.txt. Anropsstacken visar vilken metod som kördes på huvudtråden vid blockeringstillfället.
adb bugreport bugreport.zip
unzip -p bugreport.zip "*traces*" > traces.txt
Google Play Console tillhandahåller avsnittet ANR & Crash med aggregerade rapporter och felfrekvenser. För varje ANR visas anropsstacken och statistik per enhet: modell, Android-version, region. Detta gör det möjligt att identifiera ANR som beror på specifika enheter eller systemversioner.
Android Studio har sedan 2021 ANR Watchdog i profileraren. Den registrerar automatiskt en tråddump om huvudtråden inte svarar längre än tröskeltiden. Verktyget visar en tidslinje över händelser: vilka operationer som startades, vilka metoder som kördes och i vilket skede blockeringen inträffade.
Förebyggande av ANR bygger på en grundläggande regel: huvudtråden ska bara behandla UI-händelser. Alla operationer som varar längre än 16 millisekunder (tiden för en bildruta) måste utföras i en bakgrundstråd.
StrictMode — inbyggt Android-verktyg för att upptäcka potentiella ANR under utvecklingsfasen. Aktivera det i Application.onCreate() med flaggor för disk- och nätverksoperationer. Vid överträdelse kastar StrictMode ett undantag eller skriver i logcat.
if (BuildConfig.DEBUG) {
StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.build()
.let { StrictMode.setThreadPolicy(it) }
}
Kotlin Coroutines — standardsättet för asynkront arbete i moderna Android-appar. Grundteknik: I/O-operationer körs på Dispatchers.IO, resultatet skickas till Dispatchers.Main för UI-uppdatering. För Flow-liknande scenarier, använd Dispatchers.Default för CPU-intensiva uppgifter.
RxJava är fortfarande populärt i äldre projekt. subscribeOn(Schedulers.io()) och observeOn(AndroidSchedulers.mainThread()) — den minimala uppsättningen för att förebygga ANR. Samma regel: inget Observable eller Flowable bör sända data från huvudtråden.
Firebase Crashlytics från version SDK 18.4.0 stöder ANR-övervakning direkt ur lådan. För Android 11+ använder Crashlytics system-API:et ApplicationExitInfo som ger den exakta orsaken till avslutning: ANR, Crash eller systemavslutning. Aktivera anpassade nycklar med skärm- och tillståndsparametrar för kontextuell analys.
Fem verktyg täcker alla stadier av arbete med ANR: från felsökning på arbetsstationen till övervakning i produktion. Varje verktyg löser sitt eget problem och tillhandahåller data för olika scenarier.
| Verktyg | Syfte | Dataformat |
|---|---|---|
| StrictMode | Upptäckt under utveckling | Logcat / Exception |
| ANR Watchdog (Android Studio) | Realtidsspårning | Thread dump + timeline |
| Google Play Console | Aggregerad statistik | ANR rate + stack traces |
| Firebase Crashlytics | Produktionsövervakning | ApplicationExitInfo |
| adb bugreport | Fullständig systemrapport | traces.txt + logcat + dmesg |
Varje verktyg har sin egen nisch: StrictMode fångar uppenbara överträdelser i tidiga skeden, Crashlytics visar verklig ANR-frekvens hos användare, och adb bugreport ger den mest fullständiga bilden för komplexa fall. Kombinera dem för full täckning.
Firebase Performance övervakar UI-trådens svarstid och skapar automatiskt spårningar för misstänkt långa operationer. Om huvudtråden blockeras i mer än 500 ms registrerar Performance en anpassad spårning med namnet på den skyldiga metoden. Detta gör det möjligt att upptäcka ANR-scenarier utan användarens inblandning och innan de blir kritiska.
Integrationen med Firebase Crashlytics ger en fullständig bild: Performance visar nedgångar före ANR och Crashlytics — själva frysningshändelsen. Konfigurera aviseringar i Firebase Console för ANR rate över 0,1% så får du meddelanden om nya problem innan massiva användarklagomål.
Vanliga frågor
ANR — är en frysning där appen inte svarar men finns kvar i minnet. Crash — är en fullständig oväntad avslutning med processavslut. ANR kan „överlevas” om systemet eller användaren väntar på svar, medan Crash alltid avslutar appen.
Nej. ANR är inte ett Java/Kotlin-undantag, utan en systemsignal på processnivå (SIGQUIT). Utvecklaren kan inte hantera det i applikationskoden. Det enda sättet att reagera på ANR är att analysera rapporter efter omstart.
Enhetsprestanda, Android-version, CPU-belastning och antalet bakgrundsprocesser påverkar sannolikheten för ANR. På svagare enheter kan samma operation ta 2–3 gånger längre tid och överskrida 5-sekundersgränsen.
10 sekunder för vanlig BroadcastReceiver i onReceive(). För foreground-tjänster är gränsen 20 sekunder, och för ContentProvider finns ingen tydlig gräns, men blockering av huvudtråden i mer än 5 sekunder orsakar fortfarande ANR.
Aktivera StrictMode i alla debug-versioner, lägg till övervakning via Firebase Crashlytics och använd adb bugreport när ANR inträffar. Oregelbundna ANR är ofta relaterade till race conditions eller specifika nätverksförhållanden.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också