Crash-ul aplicației — terminare anormală în care programul nu mai răspunde și se închide. În dezvoltarea mobilă, crash-urile sunt principala sursă de recenzii negative și scădere a ratingului Firebase (2024), utilizatorii șterg aplicația după una-două crash-uri în 53% din cazuri. Fiecare închidere reduce reținerea cu 3–5%. Sistemele de monitorizare precum Crashlytics și Sentry ajută la găsirea rapidă și remedierea cauzelor crash-urilor înainte de a afecta masiv utilizatorii.
Principalele idei
Crash — încheierea neașteptată a programului cauzată de o situație excepțională pe care codul nu a gestionat-o. În sistemele de operare mobile, crash-ul duce la închiderea imediată a aplicației și afișarea ecranului „Aplicația s-a oprit" sau revenirea la ecranul principal
Crash-urile se împart în două clase mari. Erori gestionate — blocurile try/catch prind excepția, aplicația continuă să funcționeze, posibil cu pierderea funcționalității. Crash-uri negestionate — excepția se propagă până la nivelul sistemului de operare, iar sistemul ucide procesul. Al doilea tip este deosebit de periculos deoarece utilizatorul nu poate salva datele.
Un sistem cu două milioane de utilizatori și o rată de crash de 0,1% pierde 2 000 de utilizatori la fiecare versiune. Conform Google Play Console (2024), aplicațiile cu o rată de crash peste 1,5% sunt excluse din recomandări și pierd până la 30% din traficul organic.
NullPointerException (NPE) — regele crash-urilor în Java/Kotlin. Încercarea de a apela o metodă pe un obiect null. În Kotlin, NPE apare mai rar datorită null safety, dar este încă posibil la utilizarea operatorului !! sau la interacțiunea cu codul Java. Google (2024) estimează: NPE reprezintă 25% din toate crash-urile aplicațiilor Android.
IndexOutOfBoundsException — accesarea unui element de listă cu un index inexistent. Cauză frecventă: datele vin de la server într-un format neașteptat, iar UI încearcă să afișeze o poziție care nu există. undefined — verifică întotdeauna dimensiunea colecției înainte de accesarea prin index.
ANR (Application Not Responding) — problemă specifică Android. Firul UI este blocat mai mult de 5 secunde. Cauze principale: cereri de rețea pe firul principal, calcule grele, sincronizare cu baza de date. StrictMode în Android ajută la detectarea blocajelor firului UI în etapa de dezvoltare.
OutOfMemoryError (OOM) — aplicația a depășit limita de memorie. Pe dispozitivele mobile cu 2–4 GB RAM, OOM este o problemă frecventă la lucrul cu imagini mari sau liste infinite fără paginare. undefined — Glide/Coil pentru încărcarea imaginilor, LruCache pentru cache, ViewHolder în RecyclerView.
Runtime exceptions — erori pe care compilatorul nu le verifică în etapa de construire. Ele apar doar la executarea codului pe un dispozitiv specific cu date specifice. În Java acestea sunt RuntimeException și subclasele sale: NullPointerException, IllegalArgumentException, ArithmeticException.
Erori fatale (FATAL) — nu runtime, ci defecte de sistem. Signal 11 (SIGSEGV) — încălcarea segmentării memoriei în codul native. Signal 6 (SIGABRT) — terminarea anormală cauzată de aplicația însăși prin abort(). Astfel de crash-uri sunt greu de diagnosticat deoarece stack trace adesea nu arată un context inteligibil.
În iOS, cauzele principale sunt NSInvalidArgumentException (nil neașteptat într-un parametru) și EXC_BAD_ACCESS (acces la memorie eliberată). Swift a redus numărul de crash-uri comparativ cu Objective-C, dar erorile în runtime ObjC și bibliotecile C încă duc la defectări.
Firebase Crashlytics — standardul pentru aplicațiile mobile. Colectează automat stack trace, adaugă loguri, ID utilizator și metadate ale dispozitivului. Grupează crash-urile după semnătură (clasa erorii + linie). Real-time alerts — notificări atunci când rata de crash depășește un prag stabilit (de ex. >0,1% pe oră).
Sentry — o alternativă cu capacități mai flexibile. Permite crearea de custom contexts, adăugarea de breadcrumbs, configurarea filtrării în aplicație pentru excluderea erorilor neimportante. Source maps pentru Kotlin și Swift permit vizualizarea codului sursă, nu a numelor ofuscate.
Best practices pentru loguri: trimite metadate cheie înainte de executarea unei operații periculoase. Adaugă custom keys (numărul versiunii API, ultimul ecran, dimensiunea datelor de intrare). Aceasta transformă un stack trace inutil în informații acționabile.
class PaymentViewModel : ViewModel() {
fun processPayment(amount: Double) {
crashlytics.setCustomKey("last_screen", "payment")
crashlytics.setCustomKey("amount", amount)
try {
api.charge(amount)
} catch (e: Exception) {
crashlytics.recordException(e)
}
}
}
Optional binding undefined null safety — în Kotlin folosește `?` pentru tipuri nullable, `let` și `?:` pentru gestionarea sigură a null. În Swift — optionals și guard let. Modern Kotlin (2024) a adăugat adnotări Contract: @ContractsDsl permite declararea că o funcție nu returnează null, iar compilatorul verifică acest lucru.
Error handling undefined — fiecare cerere de rețea trebuie să gestioneze timeout, erorile de parsare și refuzul serverului. Retrofit undefined — o clasă sealed care garantează că eroarea va fi gestionată. Stilul No Exception: în loc de try/catch, folosește sealed Result pentru gestionarea explicită a succesului și erorii.
Feature flags — dezactivează funcționalitatea problematică de la distanță fără a lansa o nouă versiune. Firebase Remote Config permite modificarea comportamentului aplicației fără publicare în magazin.
Lansare graduală — lansează noua versiune pentru 5% din audiență și monitorizează rata de crash. Dacă rata rămâne sub țintă (de obicei <0,1%), extinde la 25%, apoi 50%, apoi 100%. Google Play Console și App Store Connect suportă lansări etapizate pentru oprirea automată la depășirea pragului.
1: Clasificare — determină severitatea: Critical (crash la >1% utilizatori), High (0,1–1%), Medium (<0,1%). Pentru crash-uri Critical — răspuns imediat. Google Play Console clasifică automat crash-urile după numărul de utilizatori afectați.
2: Analiza stack trace — deschide logul în Crashlytics, vezi locul exact al defectării. Verifică custom keys: ce ecran, ce date, versiunea OS. Compară cu ultima implementare — adesea crash-ul este cauzat de o modificare recentă în cod care a afectat un scenariu de utilizare neașteptat.
3: Reproducere — încearcă să reproduci crash-ul pe un dispozitiv sau emulator cu parametri similari. Dacă nu reușești, verifică logul de crash pentru modele: modele specifice (Samsung A10), versiuni Android (API < 26), locale. undefined — adaugă o condiție de protecție care acoperă scenariul.
4: Remediere și monitorizare — lansează un hotfix cu prioritate. După lansare, asigură-te că rata de crash pentru acest tip scade la zero. Scrie un test de regresie care acoperă scenariul de crash. Fără test, aceeași eroare poate reveni la următoarea refactorizare.
Întrebări frecvente
Rata de crash normală — mai puțin de 0,1% pentru versiunile de producție. Google Play recomandă menținerea ratei de crash sub 1,5%, dar aplicațiile de top (YouTube, Instagram) mențin 0,01–0,05%. Pentru lansări de funcționalități noi, se admite o creștere temporară la 0,5% cu scădere ulterioară după hotfix.
Crash — aplicația se termină anormal. ANR (Application Not Responding) — aplicația îngheață mai mult de 5 secunde, dar nu se închide forțat. Utilizatorul vede dialogul „Aplicația nu răspunde" și poate aștepta sau închide. Problemele ANR nu sunt mai puțin grave decât crash-urile și afectează și ratingul în magazin.
Dispozitivele diferite au versiuni diferite de OS, cantități de memorie, versiuni de biblioteci și chiar procesoare diferite. undefined: un crash pe Android 6 (API 23) din cauza lipsei permisiunii runtime poate să nu se reproducă pe Android 12.
Adaugă custom breadcrumbs în Crashlytics: înregistrează evenimente cheie înainte de executarea operației. Debug symbols (dSYM, ProGuard mapping) — încarcă neapărat în Crashlytics pentru a vedea numele reale ale funcțiilor, nu cele ofuscate.
În producție — niciodată. Crash-uri negestionate deteriorează experiența utilizatorului. Folosește try/catch cu logarea erorii. În modul debug, crash-ul este permis pentru feedback rapid dezvoltatorului. Assertions — pentru verificarea invarianților care nu trebuie niciodată încălcați, dar numai în versiunile de debug.
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