Se deconectează — ce este, cauze tipice și metode de rezolvare

Autor: IT Sectr Publicat: 2026-07-29 Timp de citire: 10 min

Pierderea conexiunii — unul dintre cele mai frecvente și enervante fenomene în aplicațiile mobile. Utilizatorul pierde accesul la date, operațiunea este întreruptă, aplicația îngheață sau se blochează. Conform Google Android Developer Blog, 70% dintre utilizatori șterg aplicația dacă aceasta se blochează sau îngheață de două ori. Să analizăm cauzele pierderii conexiunii și metodele de construire a comunicațiilor tolerante la erori.

Principalele puncte

  • ANR (Application Not Responding) — blocarea firului UI mai mult de 5 secunde duce la terminarea forțată
  • Offline-first — arhitectură în care stocarea locală este sursa de adevăr, iar rețeaua este mecanismul de sincronizare
  • Retry with backoff — repetarea automată a cererii cu întârziere crescândă la erori de rețea
  • ConnectivityManager — API Android pentru monitorizarea stării rețelei și adaptarea comportamentului aplicației
  • Graceful degradation — aplicația ar trebui să funcționeze (măcar parțial) în absența rețelei

Ce înseamnă „se deconectează” în aplicațiile mobile?

Se deconectează — termen utilizat de utilizatori pentru a descrie situația în care aplicația pierde conexiunea cu serverul, nu mai răspunde la acțiuni sau se termină cu o eroare. În sens tehnic, poate fi: eroare de rețea (timeout, DNS failure), ANR (blocarea firului UI), crash (excepție nehandleată) sau race condition (condiție de cursă).

Pentru utilizator, toate aceste scenarii arată la fel: aplicația încetează să funcționeze. Diferența pentru dezvoltator constă în abordarea diagnosticării și remedierii. Erorile de rețea se rezolvă cu mecanisme de retry, ANR — prin mutarea operațiunilor în afara firului UI, crash — prin gestionarea excepțiilor.

Conform Crittercism (acum Apteligent), o aplicație mobilă medie pierde 1-2% dintre utilizatori la fiecare blocare. Pentru o aplicație cu 1 milion de utilizatori, aceasta înseamnă 10-20 de mii de instalări pierdute pentru o singură eroare. Acest lucru este deosebit de critic pentru aplicațiile din sectorul financiar și medical.

Principalele cauze ale pierderii conexiunii

Rețea instabilă — dispozitivele mobile comută constant între Wi-Fi și rețeaua mobilă, intră în zone fără acoperire (metrou, lift, subsol). Fiecare comutare provoacă o pierdere temporară a conexiunii, pe care aplicația trebuie să o gestioneze corect.

Timeouturi — dacă serverul nu răspunde în timpul stabilit (de obicei 10-30 de secunde), clientul aruncă SocketTimeoutException. Timeouturile lungi fără feedback sunt percepute de utilizator ca înghețare. Se recomandă să setați timeoutul la maximum 15 secunde.

kotlin
val client = OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(15, TimeUnit.SECONDS)
    .writeTimeout(15, TimeUnit.SECONDS)
    .retryOnConnectionFailure(true)
    .build()

Condiția de cursă (race condition) — apare atunci când mai multe fire de execuție citesc și scriu simultan aceleași date fără sincronizare. De exemplu, încărcarea datelor din cache în firul UI în paralel cu actualizarea cache-ului din rețea poate duce la afișarea datelor învechite sau incorecte.

  • Excepții nehandleate în callback sau corutină duc la blocarea aplicației
  • Presiunea memoriei — sistemul ucide aplicația la lipsa de memorie pentru aplicația din prim-plan
  • Lifecycle race — operația async se finalizează după ce Activity/Fragment a fost distrus
  • Blocarea UI — executarea rețelei sau a bazei de date pe firul principal provoacă ANR după 5 secunde

Arhitectura pentru aplicații tolerante la erori

Offline-first — model arhitectural în care stocarea locală (Room, CoreData) este singura sursă de adevăr. Rețeaua este utilizată pentru sincronizarea datelor în fundal. Utilizatorul vede întotdeauna date actualizate din cache-ul local, chiar și în absența rețelei.

Repository pattern — punct unic de intrare pentru date care decide dacă să preia datele din rețea sau din cache. Repository-ul abstractizează sursa de date de ViewModel și UI. La eroare de rețea, repository-ul comută automat pe sursa locală.

kotlin
class UserRepository(
    private val api: UserApi,
    private val dao: UserDao
) {
    suspend fun getUsers(): Result<List<User>> {
        return try {
            val remote = api.fetchUsers()
            dao.insertAll(remote)
            Result.success(remote)
        } catch (e: IOException) {
            val cached = dao.getAll()
            if (cached.isNotEmpty()) {
                Result.success(cached) // returnează cache-ul la eroare de rețea
            } else {
                Result.failure(e)
            }
        }
    }
}

Circuit Breaker — model de protecție a serverului împotriva unei avalanșe de cereri când este indisponibil. După N erori consecutive, întrerupătorul se deschide și toate cererile returnează imediat eroare fără încercare de conectare. După un timeout prestabilit, întrerupătorul trece în stare semi-deschisă pentru o cerere de test.

Cum să gestionăm erorile de rețea?

Exponential backoff — mecanism standard de retry. După primul eșec așteptați 1 secundă, după al doilea — 2 secunde, apoi 4, 8, 16. Limitați numărul maxim de încercări (de obicei 3-5) pentru a nu supraîncărca serverul și bateria.

Feedback pentru utilizator — la eroare de rețea afișați un mesaj inteligibil: „Nu există conexiune”, „Serverul este temporar indisponibil”, „Verificați internetul”. Utilizați Snackbar sau Inline State View. Niciodată nu afișați utilizatorului erori tehnice (HTTP 500, SocketException).

ConnectivityManager — API Android pentru monitorizarea rețelei. Permiteți aplicației să reacționeze la schimbări: la pierderea rețelei afișați un placeholder, la restabilire — actualizați automat datele. În iOS utilizați NWPathMonitor din framework-ul Network.

kotlin
class NetworkMonitor(private val context: Context) {
    private val manager =
        context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

    fun isOnline(): Boolean {
        val network = manager.activeNetwork ?: return false
        val caps = manager.getNetworkCapabilities(network) ?: return false
        return caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    }
}

Instrumente de monitorizare și logare

Crashlytics (Firebase) — instrument standard de raportare a blocărilor pentru aplicații mobile. Colectează stacktrace-ul tuturor excepțiilor nehandleate, versiunea sistemului de operare, modelul dispozitivului și timpul blocării. Permite gruparea erorilor și atribuirea responsabililor pentru remedieri.

Sentry — alternativă la Crashlytics cu suport pentru monitorizarea performanței. Permite trasarea tranzacțiilor specifice (de exemplu, „autentificarea utilizatorului”) și vizualizarea la ce pas a apărut eroarea. Performance tracing ajută la diferențierea timeouturilor de rețea de bug-urile din logica aplicației.

Timber — bibliotecă de logare pentru Android cu adăugare automată de etichete în funcție de clasă. În compilarea debug, logați toate cererile și răspunsurile de rețea. În compilarea release — doar erorile și avertizările prin Crashlytics.setCustomLog.

InstrumentTipCând să utilizați
CrashlyticsCrash reportingÎntotdeauna în release — colectarea automată a blocărilor
SentryCrash + PerformanceCând trebuie să profilați scenarii specifice de utilizator
TimberLoggingDebug: logare completă; Release: doar erori
HTTP ToolkitNetwork debugInterceptarea și analiza locală a traficului HTTP

Conform Firebase Summit 2023, aplicațiile care au implementat Crashlytics + Performance Monitoring reduc timpul mediu de detectare și remediere a bug-urilor critice de la 3 zile la 4 ore. Se recomandă configurarea alertelor pentru fiecare blocare cu o frecvență mai mare de 0.1% din utilizatorii activi.

Întrebări frecvente

Ce să fac dacă aplicația se blochează fără mesaj de eroare?

Dacă crash-ul nu este prins în Crashlytics, verificați crash-urile native (SIGSEGV, SIGABRT) — acestea nu sunt gestionate de handler-ul de excepții Java/Kotlin. În Android, aceasta poate fi o scurgere de memorie native din JNI, în iOS — EXC_BAD_ACCESS. Utilizați Breakpad (Android) sau PLCrashReporter (iOS) pentru colectarea stacktrace-ului crash-urilor native.

Cum să reproduc o eroare care apare doar în rețea slabă?

Utilizați Network Link Conditioner (integrat în iOS, pentru Android există Facebook Network Connection Class sau setările Developer Options > Network > Select network type). Setați întârzierea la 500-3000 ms și pierderea de pachete la 5-30%. De asemenea, puteți utiliza Charles Proxy sau mitmproxy pentru emularea întârzierilor de rețea și a întreruperilor.

Cum să prevenim ANR la cererile de rețea?

ANR apare atunci când firul UI este blocat mai mult de 5 secunde. Cererile de rețea trebuie executate într-un fir de fundal: corutine (viewModelScope.launch(Dispatchers.IO)), RxJava (subscribeOn(Schedulers.io)) sau WorkManager pentru sincronizare. Setați întotdeauna timeouturi pe clientul HTTP — lipsa timeoutului poate duce la blocarea permanentă.

Ce este race condition și cum să îl evităm?

Race condition — situația în care rezultatul unei operațiuni depinde de ordinea executării firelor. De exemplu, utilizatorul apasă rapid butonul „Trimite” de două ori, iar cererea este trimisă de două ori. Soluție: utilizați Mutex, single-threaded executors sau state machine (dezactivați butonul după prima apăsare). În Kotlin, utilizați Mutex din corutine sau adnotarea @Synchronized.

Cum să testăm toleranța la erori a aplicației?

Aplicați Chaos Engineering pentru aplicații mobile: întrerupeți rețeaua în timpul operațiunilor, simulați întârziere mare, comutați între Wi-Fi și rețeaua mobilă, ucideți procesul prin sistem. Instrumente: Facebook Network Connection Class, Charles Proxy, iOS Network Link Conditioner. În CI/CD, adăugați teste UI cu diferite condiții de rețea prin AndroidTest Orchestrator.

Rezumat

  • Se deconectează — termen colectiv pentru erori de rețea, ANR, crash și race conditions; experiența utilizatorului este aceeași, cauzele diferite
  • Erorile de rețea — cea mai frecventă cauză; soluția include timeouturi (10-15 secunde), exponential backoff și arhitectura offline-first
  • ANR apare la blocarea firului UI mai mult de 5 secunde; operațiile de rețea și disc executați întotdeauna pe un fir de fundal
  • Offline-first cu Repository pattern: stocarea locală — sursa de adevăr, rețeaua — mecanismul de sincronizare
  • Crashlytics + Performance Monitoring — setul minim pentru monitorizarea producției cu alerte pe blocări frecvente
  • Condiția de cursă necesită sincronizarea firelor: Mutex, State Machine sau executor cu un singur fir
  • Testați cu emularea rețelei slabe și Chaos Engineering — doar așa puteți descoperi probleme ascunse în condiții ideale de dezvoltare

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.

Discutați proiectul

Citiți și