Megszakad — mi ez, tipikus okok és megoldási módszerek

Szerző: IT Sectr Megjelenés: 2026-07-29 Olvasási idő: 10 perc

Kapcsolat elvesztése — az egyik leggyakoribb és legidegesítőbb jelenség mobilalkalmazásokban. A felhasználó elveszíti a hozzáférést az adatokhoz, a művelet megszakad, az alkalmazás lefagy vagy összeomlik. A Google Android Developer Blog szerint a felhasználók 70%-a törli az alkalmazást, ha az kétszer összeomlik vagy lefagy. Vizsgáljuk meg a kapcsolat elvesztésének okait és a hibatűrő kommunikáció kiépítésének módjait.

Főbb pontok

  • ANR (Application Not Responding) — a UI szál 5 másodpercnél hosszabb blokkolása kényszerített befejezéshez vezet
  • Offline-first — architektúra, ahol a helyi tároló az igazság forrása, a hálózat pedig a szinkronizációs mechanizmus
  • Retry with backoff — a kérés automatikus ismétlése növekvő késleltetéssel hálózati hibák esetén
  • ConnectivityManager — Android API a hálózati állapot figyelésére és az alkalmazás viselkedésének adaptálására
  • Graceful degradation — az alkalmazásnak működnie kell (legalább részben) hálózat hiányában is

Mit jelent a „megszakad” mobilalkalmazásokban?

Megszakad — felhasználói kifejezés, amely azt a helyzetet írja le, amikor az alkalmazás elveszíti a kapcsolatot a szerverrel, nem reagál a műveletekre, vagy hibával fejeződik be. Technikai értelemben ez lehet: hálózati hiba (időtúllépés, DNS failure), ANR (UI szál blokkolása), crash (kezeletlen kivétel) vagy race condition (versenyhelyzet).

A felhasználó számára ezek a forgatókönyvek ugyanúgy néznek ki: az alkalmazás leáll. A fejlesztő számára a különbség a diagnosztika és a javítás megközelítésében rejlik. A hálózati hibák retry mechanizmusokkal oldhatók meg, az ANR a műveletek UI szálból való kiemelésével, a crash a kivételek kezelésével.

A Crittercism (ma Apteligent) szerint egy átlagos mobilalkalmazás a felhasználók 1-2%-át veszíti el minden egyes összeomláskor. Egy 1 millió felhasználós alkalmazás esetében ez 10-20 ezer elvesztett telepítést jelent hibánként. Ez különösen kritikus a pénzügyi és egészségügyi szektorban.

A kapcsolat elvesztésének fő okai

Instabil hálózat — a mobileszközök folyamatosan váltanak Wi-Fi és mobilhálózat között, lefedettség nélküli zónákba (metró, lift, pince) kerülnek. Minden váltás átmeneti kapcsolatvesztést okoz, amelyet az alkalmazásnak megfelelően kell kezelnie.

Időtúllépések — ha a szerver nem válaszol a beállított időn belül (általában 10-30 másodperc), a kliens SocketTimeoutException-t dob. A hosszú időtúllépések visszajelzés nélkül a felhasználó által lefagyásként érzékelhetők. Javasolt az időtúllépést legfeljebb 15 másodpercre beállítani.

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

Versenyhelyzet (race condition) — akkor keletkezik, amikor több szál egyidejűleg olvassa és írja ugyanazokat az adatokat szinkronizálás nélkül. Például az adatok gyorsítótárból való betöltése a UI szálban párhuzamosan a gyorsítótár hálózatból való frissítésével elavult vagy helytelen adatok megjelenítéséhez vezethet.

  • Kezeletlen kivételek a callback-ben vagy coroutine-ban az alkalmazás összeomlásához vezetnek
  • Memórianyomás — a rendszer megöli az alkalmazást, ha nincs elég memória az előtér-alkalmazás számára
  • Lifecycle race — az async művelet az Activity/Fragment megsemmisítése után fejeződik be
  • UI blokkolása — a hálózat vagy adatbázis főszálon való futtatása 5 másodperc után ANR-t okoz

Architektúra hibatűrő alkalmazásokhoz

Offline-first — architekturális minta, ahol a helyi tároló (Room, CoreData) az egyetlen igazságforrás. A hálózat a háttérben történő adatszinkronizáláshoz használatos. A felhasználó mindig naprakész adatokat lát a helyi gyorsítótárból, még hálózat hiányában is.

Repository pattern — egységes belépési pont az adatokhoz, amely eldönti, hogy az adatokat a hálózatból vagy a gyorsítótárból vegye-e. A repository elválasztja az adatforrást a ViewModel-től és a UI-tól. Hálózati hiba esetén a repository automatikusan átkapcsol a helyi forrásra.

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) // gyorsítótár visszaadása hálózati hibánál
            } else {
                Result.failure(e)
            }
        }
    }
}

Circuit Breaker — a szerver védelmére szolgáló minta a kérések áradatától, amikor az nem elérhető. N egymást követő hiba után a megszakító kinyílik, és minden kérés azonnal hibát ad vissza kapcsolódási kísérlet nélkül. Egy meghatározott időtúllépés után a megszakító félnyitott állapotba kerül egy próbakéréshez.

Hogyan kezeljük a hálózati hibákat?

Exponential backoff — standard retry mechanizmus. Az első sikertelenség után várjon 1 másodpercet, a második után 2 másodpercet, majd 4, 8, 16. Korlátozza a maximális próbálkozások számát (általában 3-5), hogy ne terhelje túl a szervert és az akkumulátort.

Felhasználói visszajelzés — hálózati hiba esetén jelenítsen meg érthető üzenetet: „Nincs kapcsolat”, „A szerver átmenetileg nem elérhető”, „Ellenőrizze az internetet”. Használjon Snackbar-t vagy Inline State View-t. Soha ne mutasson technikai hibákat (HTTP 500, SocketException) a felhasználónak.

ConnectivityManager — Android API a hálózat figyeléséhez. Engedje, hogy az alkalmazás reagáljon a változásokra: hálózat elvesztésekor jelenítsen meg placeholdert, helyreálláskor automatikusan frissítse az adatokat. iOS-ben használja a NWPathMonitor-t a Network keretrendszerből.

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)
    }
}

Monitorozási és naplózási eszközök

Crashlytics (Firebase) — standard összeomlás-jelentő eszköz mobilalkalmazásokhoz. Összegyűjti az összes kezeletlen kivétel stacktrace-ét, az operációs rendszer verzióját, az eszköz modelljét és az összeomlás idejét. Lehetővé teszi a hibák csoportosítását és a javításokért felelős személyek kijelölését.

Sentry — a Crashlytics alternatívája teljesítményfigyelő támogatással. Lehetővé teszi konkrét tranzakciók (pl. „felhasználó hitelesítése”) nyomon követését és annak megtekintését, hogy melyik lépésnél történt a hiba. Performance tracing segít megkülönböztetni a hálózati időtúllépéseket az alkalmazás logikájában lévő hibáktól.

Timber — naplózási könyvtár Androidhoz automatikus osztály szerinti címkék hozzáadásával. Debug buildben naplózza az összes hálózati kérést és választ. Release buildben — csak a hibákat és figyelmeztetésekat a Crashlytics.setCustomLog segítségével.

EszközTípusMikor használjuk
CrashlyticsCrash reportingMindig release-ben — automatikus összeomlásgyűjtés
SentryCrash + PerformanceAmikor konkrét felhasználói forgatókönyveket kell profilozni
TimberLoggingDebug: teljes naplózás; Release: csak hibák
HTTP ToolkitNetwork debugHTTP forgalom helyi elfogása és elemzése

A Firebase Summit 2023 szerint azok az alkalmazások, amelyek bevezették a Crashlytics + Performance Monitoringot, a kritikus hibák észlelésének és javításának átlagos idejét 3 napról 4 órára csökkentik. Javasolt riasztást beállítani minden olyan összeomlásra, amelynek gyakorisága meghaladja az aktív felhasználók 0,1%-át.

Gyakran ismételt kérdések

Mit tegyünk, ha az alkalmazás hibaüzenet nélkül összeomlik?

Ha a crash nem fogható el a Crashlytics-ben, ellenőrizze a natív összeomlásokat (SIGSEGV, SIGABRT) — ezeket nem kezeli a Java/Kotlin kivételkezelő. Androidben ez lehet natív memóriaszivárgás JNI-ből, iOS-ben EXC_BAD_ACCESS. Használja a Breakpad (Android) vagy PLCrashReporter (iOS) eszközt a natív crash stacktrace összegyűjtéséhez.

Hogyan reprodukálható az a hiba, amely csak gyenge hálózatnál jelentkezik?

Használja a Network Link Conditioner-t (beépítve iOS-ben, Androidhoz Facebook Network Connection Class vagy a Developer Options > Network > Select network type beállítások). Állítsa be a késleltetést 500-3000 ms-ra és a csomagvesztést 5-30%-ra. Használhatja továbbá a Charles Proxy-t vagy a mitmproxy-t a hálózati késleltetések és megszakítások szimulálására.

Hogyan előzhető meg az ANR hálózati kéréseknél?

ANR akkor keletkezik, ha a UI szál 5 másodpercnél hosszabb ideig blokkolt. A hálózati kéréseket háttérszálon kell végrehajtani: coroutines (viewModelScope.launch(Dispatchers.IO)), RxJava (subscribeOn(Schedulers.io)) vagy WorkManager a szinkronizáláshoz. Mindig állítson be időtúllépést a HTTP kliensen — az időtúllépés hiánya örök blokkoláshoz vezethet.

Mi a race condition és hogyan kerülhető el?

Race condition — olyan helyzet, amikor a művelet eredménye a szálak végrehajtási sorrendjétől függ. Például a felhasználó gyorsan kétszer megnyomja a „Küldés” gombot, és a kérés kétszer kerül elküldésre. Megoldás: használjon Mutex-et, single-threaded executors-t vagy state machine-t (tiltsa le a gombot az első megnyomás után). Kotlinban használja a Mutex-et a coroutines-ből vagy a @Synchronized annotációt.

Hogyan teszteljük az alkalmazás hibatűrését?

Alkalmazzon Chaos Engineering-et mobilalkalmazásokra: kapcsolja ki a hálózatot műveletek közben, szimuláljon nagy késleltetést, váltson Wi-Fi és mobilhálózat között, ölesse meg a folyamatot a rendszerrel. Eszközök: Facebook Network Connection Class, Charles Proxy, iOS Network Link Conditioner. CI/CD-ben adjon hozzá UI teszteket különböző hálózati körülményekkel az AndroidTest Orchestrator segítségével.

Összegzés

  • Megszakad — gyűjtőfogalom a hálózati hibákra, ANR-re, crash-re és race condition-re; a felhasználói élmény ugyanaz, az okok különbözőek
  • Hálózati hibák — a leggyakoribb ok; a megoldás időtúllépéseket (10-15 másodperc), exponential backoff-ot és offline-first architektúrát foglal magában
  • ANR akkor keletkezik, ha a UI szál 5 másodpercnél hosszabb ideig blokkolt; a hálózati és lemezműveleteket mindig háttérszálon végezze
  • Offline-first Repository pattern-nel: helyi tároló — igazság forrása, hálózat — szinkronizációs mechanizmus
  • Crashlytics + Performance Monitoring — minimális készlet a production monitorozáshoz riasztásokkal a gyakori összeomlásokra
  • Versenyhelyzet a szálak szinkronizálását igényli: Mutex, State Machine vagy egyszálú executor
  • Tesztelje gyenge hálózat szimulációjával és Chaos Engineering-gel — csak így fedezheti fel az ideális fejlesztési körülmények között rejtve maradó problémákat

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is