Crash aplikace — nouzové ukončení, při kterém program přestává reagovat a zavírá se. V mobilním vývoji jsou crashe hlavním zdrojem negativních recenzí a poklesu hodnocení. Podle údajů Firebase (2024), uživatelé mažou aplikaci po jednom nebo dvou crashech v 53 % případů. Každé zavření snižuje retenci o 3–5 %. Monitorovací systémy jako Crashlytics a Sentry pomáhají rychle najít a opravit příčiny crashů, než masivně ovlivní uživatele.
Hlavní body
Crash — neočekávané ukončení programu způsobené výjimečnou situací, kterou kód neošetřil. V mobilních OS vede crash k okamžitému zavření aplikace a zobrazení obrazovky „Aplikace byla zastavena“ nebo návratu na domovskou obrazovku.
Crashe se dělí do dvou velkých tříd. Ošetřené chyby — bloky try/catch zachytí výjimku, aplikace pokračuje v činnosti, možná se ztrátou funkčnosti. Neošetřené crashe — výjimka se propaguje až na úroveň OS a systém zabije proces. Druhý typ je obzvláště nebezpečný, protože uživatel nemůže uložit data.
Systém se dvěma miliony uživatelů a 0,1% crash rate ztrácí 2 000 uživatelů při každém vydání. Podle Google Play Console (2024) jsou aplikace s crash rate nad 1,5 % vyloučeny z doporučení a ztrácejí až 30 % organické návštěvnosti.
NullPointerException (NPE) — král crashů v Java/Kotlin. Pokus o volání metody na null objektu. V Kotlinu se NPE vyskytuje méně často díky null safety, ale je stále možný při použití operátoru !! nebo interakci s Java kódem. Google (2024) odhaduje: NPE tvoří 25 % všech crashů Android aplikací.
IndexOutOfBoundsException — přístup k prvku seznamu s neexistujícím indexem. Častá příčina: data přicházejí ze serveru v neočekávaném formátu a UI se snaží zobrazit pozici, která neexistuje. Řešení — vždy zkontroluj velikost kolekce před přístupem přes index.
ANR (Application Not Responding) — problém specifický pro Android. UI vlákno je blokováno déle než 5 sekund. Hlavní příčiny: síťové požadavky na hlavním vlákně, těžké výpočty, synchronizace s databází. StrictMode v Androidu pomáhá odhalit blokování UI vlákna ve fázi vývoje.
OutOfMemoryError (OOM) — aplikace překročila limit paměti. Na mobilních zařízeních s 2–4 GB RAM je OOM častý problém při práci s velkými obrázky nebo nekonečnými seznamy bez stránkování. Řešení — Glide/Coil pro načítání obrázků, LruCache pro cache, ViewHolder v RecyclerView.
Runtime exceptions — chyby, které kompilátor nekontroluje ve fázi sestavení. Projevují se pouze při provádění kódu na konkrétním zařízení s konkrétními daty. V Javě jsou to RuntimeException a jeho podtřídy: NullPointerException, IllegalArgumentException, ArithmeticException.
Fatální chyby (FATAL) — ne runtime, ale systémové poruchy. Signal 11 (SIGSEGV) — porušení segmentace paměti v nativním kódu. Signal 6 (SIGABRT) — nouzové ukončení způsobené samotnou aplikací pomocí abort(). Takové crashe je obtížné diagnostikovat, protože stack trace často neukazuje srozumitelný kontext.
V iOS jsou hlavními příčinami NSInvalidArgumentException (neočekávané nil v parametru) a EXC_BAD_ACCESS (přístup k uvolněné paměti). Swift snížil počet crashů ve srovnání s Objective-C, ale chyby v ObjC runtime a C knihovnách stále vedou k pádům.
Firebase Crashlytics — standard pro mobilní aplikace. Automaticky sbírá stack trace, přidává logy, ID uživatele a metadata zařízení. Seskupuje crashe podle signatury (třída chyby + řádek). Real-time alerts — upozornění, když crash rate překročí nastavenou hranici (např. >0,1 % za hodinu).
Sentry — alternativa s flexibilnějšími možnostmi. Umožňuje vytvářet vlastní kontexty, přidávat breadcrumbs, konfigurovat filtrování v aplikaci pro vyloučení nedůležitých chyb. Source maps pro Kotlin a Swift umožňují vidět zdrojový kód, ne obfuskovaná jména.
Best practices pro logy: posílejte klíčová metadata před provedením nebezpečné operace. Přidejte custom keys (číslo verze API, poslední obrazovka, velikost vstupních dat). Tím se zbytečný stack trace promění v použitelné informace.
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 a null safety — v Kotlinu použij `?` pro nullable typy, `let` a `?:` pro bezpečné zpracování null. Ve Swiftu — optionals a guard let. Modern Kotlin (2024) přidal anotace Contract: @ContractsDsl umožňuje deklarovat, že funkce nevrací null, a kompilátor to kontroluje.
Error handling v síti — každý síťový požadavek musí zpracovat timeout, chyby parsování a odmítnutí serveru. Retrofit s typem Result — sealed třída, která zaručuje, že chyba bude zpracována. Styl No Exception: místo try/catch použij sealed Result pro explicitní zpracování úspěchu a chyby.
Feature flags — deaktivujte problematickou funkčnost na dálku bez vydání nové verze. Firebase Remote Config umožňuje změnit chování aplikace bez publikace v obchodě.
Postupné zavádění — vydávejte novou verzi pro 5 % publika a sledujte crash rate. Pokud rate zůstává pod cílem (obvykle <0,1 %), rozšiřte na 25 %, poté 50 %, poté 100 %. Google Play Console a App Store Connect podporují fázové zavádění pro automatické zastavení při překročení prahu.
1: Klasifikace — určete závažnost: Critical (crash u >1 % uživatelů), High (0,1–1 %), Medium (<0,1 %). Pro Critical crashe — okamžitá reakce. Google Play Console automaticky klasifikuje crashe podle počtu postižených uživatelů.
2: Analýza stack trace — otevřete log v Crashlytics, podívejte se na přesné místo pádu. Zkontrolujte custom keys: jaká obrazovka, jaká data, verze OS. Porovnejte s posledním nasazením — často je crash způsoben nedávnou změnou v kódu, která ovlivnila neočekávaný scénář použití.
3: Reprodukce — zkuste reprodukovat crash na zařízení nebo emulátoru s podobnými parametry. Pokud se nedaří, zkontrolujte crash log na vzory: konkrétní modely (Samsung A10), verze Android (API < 26), locale. Řešení — přidejte ochrannou podmínku, která pokrývá scénář.
4: Oprava a monitorování — vydajte hotfix s prioritou. Po vydání se ujistěte, že crash rate pro tento typ klesne na nulu. Napište regresní test který pokrývá scénář crashu. Bez testu se stejná chyba může vrátit při příštím refaktoringu.
Často kladené otázky
Normální crash rate — méně než 0,1 % pro produkční vydání. Google Play doporučuje udržovat crash rate pod 1,5 %, ale špičkové aplikace (YouTube, Instagram) udržují 0,01–0,05 %. Pro vydání nové funkcionality je povolen dočasný nárůst až na 0,5 % s následným poklesem po hotfixu.
Crash — aplikace se nouzově ukončí. ANR (Application Not Responding) — aplikace zamrzne na více než 5 sekund, ale není násilně uzavřena. Uživatel vidí dialog „Aplikace neodpovídá“ a může počkat nebo zavřít. Problémy ANR nejsou o nic méně závažné než crashe a také ovlivňují hodnocení v obchodě.
Různá zařízení mají různé verze OS, množství paměti, verze knihoven a dokonce i procesory. Příklad: crash na Android 6 (API 23) kvůli chybějícímu runtime oprávnění se nemusí reprodukovat na Android 12.
Přidejte custom breadcrumbs v Crashlytics: zaznamenávejte klíčové události před provedením operace. Debug symbols (dSYM, ProGuard mapping) — nahrajte je do Crashlytics, abyste viděli skutečná jména funkcí, ne obfuskovaná.
V produkci — nikdy. Neošetřené crashe zhoršuje uživatelský zážitek. Použijte try/catch s logováním chyby. V debug režimu je crash povolen pro rychlou zpětnou vazbu vývojáři. Assertions — pro kontrolu invariantů, které by nikdy neměly být porušeny, ale pouze v debug sestaveních.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také