Kihagyás

Aszinkronitás, API kommunikáció és perzisztencia

Ez az anyag segít átlátni a mobilfejlesztés egyik legkritikusabb részét: hogyan kommunikáljunk a külvilággal és hogyan tároljuk az adatokat anélkül, hogy a felhasználó agyára mennénk egy lefagyott gombbal vagy egy üres fehér képernyővel.

Az aszinkronitás elmélete: Miért ne fagyasszuk le a világot?

A "Szent" UI Thread

Minden mobilalkalmazás lelke a Main (vagy UI) Thread. Ez a szál felelős mindenért, amit a felhasználó lát: a gombok rajzolásáért, az animációkért és az érintések feldolgozásáért.

  • Az aranyszabály: Soha ne végezz rajta nehéz műveletet (hálózati hívás, fájlba írás)!
  • A következmény: Ha a UI szál 5 másodpercnél tovább várakozik, jön az ANR (Application Not Responding) párbeszédablak, a felhasználó pedig törli az appodat.

Párhuzamosság vs. Egyidejűség (Concurrency vs. Parallelism)

Sokan keverik, de fontos különbség:

  • Concurrency: Több feladattal foglalkozunk egyszerre (pl. elindítunk egy letöltést, de közben hagyjuk a felhasználót görgetni). Nem biztos, hogy egyszerre is futnak, csak "váltogatunk" köztük.
  • Parallelism: Valóban, fizikailag egyszerre futnak a műveletek (többmagos processzorokon).

A sötét oldal: Race Condition és Deadlock

Amikor több szálon dolgozunk, jönnek a bajok:

  • Race Condition: Erre hozok egy példát: Ketten álltok a MediaMarktban az utolsó leárazott Ályfon előtt. Mindketten egyszerre nyúltok érte. A helyzet: Ha nincs „szinkronizáció” (pl. egy eladó, aki megmondja, kié volt az első érintés), akkor elszakad a doboz, és egyikőtöknek sem lesz tévéje, vagy mindketten kifizetitek, de csak egyikőtök viszi haza. Programozásnál ez az, amikor két szál egyszerre akarja ugyanazt a változót átírni, és a végeredmény totális káosz lesz.
  • Deadlock: "A vár B-re hogy nyomtasson, B vár A-ra hogy nyomtasson, én meg kidobtam a nyomtatót az ablakon, szóval sosem tudjuk meg a végeredményt"

Az aszinkronitás evolúciója

Régen Callback-eket használtunk (függvény a függvényben), ami elvezetett a Callback Hell-hez (olvashatatlan kód). Ezt váltották a Promise/Future objektumok, majd megérkezett a modern megváltás: az async/await. Ez lehetővé teszi, hogy aszinkron kódot úgy írjunk, mintha szekvenciális (egymás utáni) lenne, így emberi ésszel is felfogható marad.

Networking: Beszélgessünk a szerverrel

A "Három Állapot" szabálya

Bármilyen API hívást végzel, a kódodnak (és a UI-nak) kötelező kezelnie ezt a hármast:

  • Loading: Pörögjön a homokóra/shimmer, hogy a felhasználó tudja: dolgozunk.
  • Success: Megérkezett az adat, jelenítsük meg.
  • Error: Hiba történt (nincs net, 500-as szerverhiba). Ne csak egy üres képernyő legyen, mondjuk meg mi a baj! Légyszi ne legyünk olyanok, hogy "Valami hiba történt".

Hibakezelés: Exponential Backoff

Ha egy hívás sikertelen, nem bombázzuk a szervert másodpercenként. Használjunk exponenciális várakozást: várj 1 másodpercet, aztán 2-t, 4-et, 8-at... és adj hozzá egy kis véletlenszerűséget (jitter), hogy ne minden kliens egyszerre támadja be a szervert a javulás után.

Reaktív folyamatok (Streams)

Néha nem egyetlen adat kell, hanem adatok folyama (pl. tőzsdei árfolyamok). Erre használjuk a Reactive Streams-et (Androidon Flow, iOS-en Combine, Flutterben Stream). Itt operátorokkal (map, filter) alakíthatjuk az adatfolyamot útközben.

Perzisztencia: Hogy ne felejtsünk el semmit

Offline-First gondolkodás

Egy profi app nem omlik össze, ha éppen a metró alagútjában nyomogatjuk. Az adatokat elmentjük helyben, és ha van net, szinkronizálunk.

  • ACID: A tranzakciók alapköve. Garantálja, hogy egy mentés vagy teljesen sikerül, vagy semennyire (nincs félkész adat).
  • CAP tétel: Egy elosztott rendszerben csak kettő választható: Consistency (Konzisztencia), Availability (Rendelkezésre állás), Partition tolerance (Hálózatkimaradás-tűrés). - Ez elsősorban akkor fontos, ha hálózati hiba van. Bővebben erről itt olvashatsz.

Tárolási típusok

  • Key-Value: Egyszerű beállításokhoz (pl. "Dark Mode: ON").
  • Relációs (SQLite): Strukturált adatokhoz (pl. felhasználók és a hozzájuk tartozó posztok).
  • Document-based: Rugalmas, sémamentes tárolás. (pl: MongoDB)

Fontos minták (Patterns)

  • Repository Pattern: Az app "Single Source of Truth" (egyetlen igazságforrás) pontja. A UI nem tudja, hogy az adat a netről jön vagy a helyi adatbázisból – a Repository dönti el.
  • Optimistic Update: "Légy optimista!" Ha a felhasználó lájkol egy posztot, azonnal színezd ki a szívecskét, és csak a háttérben küldd el az API-nak. Ha hiba van, vond vissza (rollback).

Technológiai Gyorsnézet

Platform Aszinkronitás Networking Adatbázis
Android Coroutines, Flow Retrofit, OkHttp Room, DataStore
iOS async/await, Tasks URLSession, Alamofire SwiftData, CoreData
Flutter Future, Stream Dio, http Hive, Isar, Drift

AI Promptok

"Generálj egy [PLATFORM: Android/iOS/Flutter] kódot egy REST API híváshoz, amely kezeli a Loading, Success és Error állapotokat egy Sealed Class/Enum segítségével. Implementálj egy egyszerű Retry logikát is!" "Írj egy Repository osztályt, ami megvalósítja a Cache-Aside stratégiát: először a helyi adatbázisban (pl. Room/SwiftData) keresi az adatot, ha nincs ott, letölti a hálózatról és elmenti a cache-be." "Magyarázd el példakóddal, hogyan tudok Race Condition-t elkerülni, ha egy felhasználó túl gyorsan kattint egymás után egy 'Küldés' gombra [PLATFORM] környezetben."

Irodalomjegyzék