ANR (Application Not Responding) — este o notificare de sistem Android care apare atunci când aplicația nu mai răspunde la intrarea utilizatorului mai mult de 5 secunde. Potrivit Android Developers, cauza principală sunt operațiile lungi pe firul principal, care blochează procesarea atingerilor și randarea interfeței. Înțelegerea mecanismelor ANR este necesară pentru fiecare dezvoltator Android pentru a crea aplicații receptive.
Principalele puncte
ANR (Application Not Responding) — este o fereastră de dialog a sistemului de operare Android care apare atunci când aplicația nu mai răspunde la intrarea utilizatorului. Sistemul urmărește timpul de procesare a evenimentelor prin InputDispatcher: dacă o atingere sau apăsarea unui buton nu este procesată în 5 secunde, Android afișează un dialog cu propunerea de a închide sau aștepta aplicația.
Mecanismul ANR protejează experiența utilizatorului de aplicațiile înghețate. Android nu permite unei singure aplicații să blocheze înntregul sistem — spre deosebire de sistemele Desktop, platforma mobilă limitează forțat timpul de procesare a evenimentelor. BroadcastReceiver are o limită de 10 secunde, iar serviciul foreground — 20 de secunde.
ANR NU este o excepție în cod — este un mecanism de sistem la nivelul proceselor Linux. Android trimite semnalul SIGQUIT procesului, după care sistemul salvează stiva de apeluri a tuturor firelor în fișierul traces.txt. Dezvoltatorul primește ANR nu ca o excepție catch, ci ca un raport după repornirea aplicației. Pe Android 11+ a apărut API-ul ApplicationExitInfo, care permite obținerea programatică a cauzei de încheiere a procesului, inclusiv ANR — simplificând colectarea statisticilor fără parsarea manuală a traces.txt.
Cinci categorii de operații duc constant la ANR în aplicațiile Android. Fiecare dintre ele blochează firul principal, împiedicând sistemul să proceseze evenimentele de intrare și să redeseneze ecranul.
Cererile HTTP sincrone executate pe firul UI — cea mai frecventă cauză de ANR la dezvoltatorii începători. Chiar și o cerere rapidă la server poate dura 1–3 secunde, iar la o conexiune slabă — 30 de secunde sau mai mult. Android interzice explicit operațiile de rețea pe firul principal începând cu API 11, aruncând NetworkOnMainThreadException.
Utilizați Coroutines sau RxJava pentru apeluri asincrone. Corutinele cu dispatcherul Dispatchers.IO execută cererea în firul de fundal, iar rezultatul este transmis pe cel principal prin Dispatchers.Main. Aceasta elimină complet blocarea firului UI de către operațiile de rețea.
fun fetchUserData() {
CoroutineScope(Dispatchers.Main).launch {
val result = withContext(Dispatchers.IO) {
api.getUserData() // operație de fundal
}
updateUI(result) // rezultat pe firul principal
}
}
Procesarea matricelor mari de date, analiza JSON sau XML, lucrul direct cu bitmap pe firul principal — a doua cauză ca frecvență a ANR. Chiar și 300 de milisecunde de lucru continuu pe firul UI fără revenirea la bucla de evenimente cauzează o întârziere vizibilă de randare, iar valoarea limită de 5 secunde este înregistrată ca ANR.
WorkManager și serviciile de fundal sunt concepute pentru a muta calculele grele de pe firul principal. Utilizați AsyncTask (învechit), ListenableFuture sau Kotlin Flow pentru a transmite date în porții, fără a bloca UI.
Deadlock apare atunci când două fire dețin blocări și se așteaptă reciproc. Dacă unul dintre fire este cel principal, sistemul înregistrează ANR exact după 5 secunde. Thread.join(), CountDownLatch.await() și blocurile synchronized apelate de pe firul UI comportă risc de blocare.
Evitați orice operații de blocare pe firul principal. În loc de synchronized utilizați ConcurrentHashMap, în loc de Thread.join() — corutine cu async/await. Această regulă este valabilă pentru orice limbaj în Android: Java, Kotlin sau C++ prin JNI.
BroadcastReceiver se execută implicit pe firul principal. Dacă onReceive() este ocupat mai mult de 10 secunde, Android afișează ANR. Încărcarea datelor din baza de date sau rețea în interiorul onReceive este o cale garantată spre înghețare.
Utilizați goAsync() în interiorul BroadcastReceiver pentru a comuta pe firul de fundal sau registerReceiver cu getBackgroundBroadcastReceiver(). Aceasta permite procesarea evenimentelor fără blocarea UI.
Interogările grele către ContentProvider sau lucrul direct cu SQLite pe firul UI — o cauză mai puțin evidentă, dar frecventă de ANR. La migrarea bazei de date sau inserarea în masă a miilor de înregistrări, timpul de execuție poate depăși limita de 5 secunde.
Mutați toate operațiile cu baza de date în firele de fundal prin Room cu funcții suspend. Room verifică automat dacă interogarea nu se execută pe firul principal și aruncă o excepție în caz de încălcare.
Diagnosticarea ANR diferă de depanarea excepțiilor obișnuite — nu puteți prinde ANR în try-catch. Sursa principală de informații este fișierul traces.txt, pe care Android îl creează în momentul înghețării.
traces.txt conține stiva de apeluri a tuturor firelor aplicației la momentul ANR. Pentru a citi fișierul de pe un dispozitiv real, executați comanda adb bugreport, care colectează un raport complet al sistemului, inclusiv toate ANR-urile recente. Pentru emulator, fișierul este disponibil în /data/anr/traces.txt. Stiva de apeluri arată ce metodă se executa pe firul principal în momentul blocării.
adb bugreport bugreport.zip
unzip -p bugreport.zip "*traces*" > traces.txt
Google Play Console oferă secțiunea ANR & Crash cu rapoarte agregate și frecvențe de erori. Pentru fiecare ANR este afișată stiva de apeluri și statistici pe dispozitive: model, versiune Android, regiune. Aceasta permite identificarea ANR-urilor care depind de dispozitive sau versiuni specifice de sistem.
Android Studio din 2021 conține ANR Watchdog în profilator. Acesta înregistrează automat dump-ul firelor dacă firul principal nu răspunde mai mult decât timpul prag. Instrumentul arată axa temporală a evenimentelor: ce operații au fost lansate, ce metode au fost executate și în ce etapă a avut loc blocarea.
Prevenirea ANR se bazează pe o singură regulă fundamentală: firul principal trebuie să proceseze doar evenimentele UI. Orice operație care durează mai mult de 16 milisecunde (timpul unui cadru) trebuie executată în firul de fundal.
StrictMode — instrumentul integrat Android pentru detectarea ANR-urilor potențiale în faza de dezvoltare. Activați-l în Application.onCreate() cu flaguri pentru operații de disc și rețea. La încălcare, StrictMode aruncă o excepție sau scrie în logcat.
if (BuildConfig.DEBUG) {
StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.build()
.let { StrictMode.setThreadPolicy(it) }
}
Kotlin Coroutines — metoda standard de lucru asincron în aplicațiile Android moderne. Principiul de bază: operațiile de intrare-ieșire se execută pe Dispatchers.IO, rezultatul este transmis pe Dispatchers.Main pentru actualizarea UI. Pentru scenarii Flow, utilizați Dispatchers.Default pentru sarcini intensive CPU.
RxJava rămâne popular în proiectele vechi. subscribeOn(Schedulers.io()) și observeOn(AndroidSchedulers.mainThread()) — setul minim pentru prevenirea ANR. Aceeași regulă: niciun Observable sau Flowable nu ar trebui să emită date de pe firul principal.
Firebase Crashlytics de la versiunea SDK 18.4.0 acceptă monitorizarea ANR din cutie
. Pentru Android 11+ Crashlytics folosește API-ul de sistem ApplicationExitInfo, care oferă cauza exactă de încheiere: ANR, Crash sau uciderea de către sistem. Activați chei personalizate cu parametri de ecran și stare pentru analiza contextuală.
Cinci instrumente acoperă toate etapele de lucru cu ANR: de la depanare pe stația de lucru până la monitorizare în producție. Fiecare instrument își rezolvă sarcina și oferă date pentru diferite scenarii.
| Instrument | Scop | Format date |
|---|---|---|
| StrictMode | Detectare în faza de dezvoltare | Logcat / Exception |
| ANR Watchdog (Android Studio) | Urmărire în timp real | Thread dump + timeline |
| Google Play Console | Statistici agregate | ANR rate + stack traces |
| Firebase Crashlytics | Monitorizare producție | ApplicationExitInfo |
| adb bugreport | Raport complet de sistem | traces.txt + logcat + dmesg |
Fiecare instrument are propria sa nișă: StrictMode prinde încălcările evidente în stadiile incipiente, Crashlytics arată frecvența reală a ANR la utilizatori, iar adb bugreport oferă cea mai completă imagine pentru cazurile complexe. Combinați-le pentru o acoperire completă.
Firebase Performance urmărește timpul de răspuns al firului UI și creează automat trasee pentru operațiile suspect de lungi. Dacă firul principal se blochează mai mult de 500 ms, Performance înregistrează un trasou personalizat cu numele metodei vinovate. Aceasta permite detectarea scenariilor ANR fără participarea utilizatorului și înainte ca acestea să devină critice.
Integrarea cu Firebase Crashlytics oferă o imagine completă: Performance arată încetinirile înainte de ANR, iar Crashlytics — însuși faptul înghețării. Configurați alerte în Firebase Console pentru evenimentul ANR rate peste 0.1% și veți primi notificări despre probleme noi înaintea plângerilor în masă ale utilizatorilor.
întrebări frecvente
ANR — este o înghețare în care aplicația nu răspunde, dar rămâne în memorie. Crash — încheierea completă de urgență cu ieșirea din proces. ANR poate fi supraviețuit
dacă sistemul sau utilizatorul așteaptă răspunsul, iar Crash încheie întotdeauna aplicația.
Nu. ANR nu este o excepție Java/Kotlin, ci un semnal de sistem la nivel de procese (SIGQUIT). Dezvoltatorul nu poate să-l proceseze în codul aplicației. Singurul mod de a reacționa la ANR este să analizați rapoartele după repornire.
Performanța dispozitivului, versiunea Android, încărcarea CPU și numărul de procese de fundal influențează probabilitatea ANR. Pe dispozitivele slabe, aceeași operație poate dura de 2–3 ori mai mult, depășind limita de 5 secunde.
10 secunde pentru BroadcastReceiver obișnuit în onReceive(). Pentru serviciile foreground limita este de 20 de secunde, iar pentru ContentProvider nu există o limită explicită, dar blocarea firului principal mai mult de 5 secunde tot provoacă ANR.
Activați StrictMode în toate build-urile de debug, adăugați monitorizare prin Firebase Crashlytics și utilizați adb bugreport când apare ANR. ANR-urile neregulate sunt adesea legate de condiții de cursă (race condition) sau stări specifice de rețea.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și