DEX (Dalvik Executable) je formát bytekódu, do kterého je kompilován zdrojový kód Android aplikací v Javě a Kotlinu. Soubory DEX jsou spouštěny virtuálním strojem Dalvik (do Android 4.4) nebo Android Runtime (ART, od Android 5.0). Podle údajů Android Open Source Project, 2026 poskytuje formát DEX v průměru 30% kompaktnější reprezentaci kódu ve srovnání se standardním bytekódem JVM.
Hlavní body
DEX (Dalvik Executable) je formát bytekódu navržený speciálně pro mobilní zařízení Android. Na rozdíl od standardního Java bytekódu (soubory .class) je DEX optimalizován pro omezené zdroje: méně paměti, menší velikost a rychlejší načítání tříd.
Zdrojový kód v Java nebo Kotlin je kompilován javac/kotlinc do standardních souborů .class (Java bytekód). Poté nástroj d8 (nebo dříve dx) převede .class do jednoho nebo více souborů DEX. Tento převod není pouhé přebalení — d8 provádí optimalizace: slučuje konstantní fondy, přepisuje instrukce do registrové architektury a odstraňuje duplicitní data.
DEX používá registrovou architekturu (na rozdíl od zásobníkové JVM). Každá metoda má pevný počet registrů (až 65536). Instrukce DEX jsou kratší — v průměru 2 bajty oproti 1–4 bajtům v JVM. To poskytuje kompaktnější kód: typická aplikace se zmenší z 10–15 MB .class na 4–6 MB .dex.
Soubor DEX má přesně definovanou binární strukturu. Každý soubor začíná hlavičkou a obsahuje několik sekcí, které na sebe odkazují pomocí offsetů.
| Sekce | Účel |
|---|---|
| header | Hlavička: magic, kontrolní součet, podpis, velikosti a offsety sekcí |
| string_ids | Tabulka řetězců: názvy tříd, metod, polí |
| type_ids | Typy: odkazy na identifikátory řetězců typů |
| proto_ids | Prototypy metod: návratový typ a parametry |
| field_ids | Pole tříd: třída, typ, název |
| method_ids | Metody: třída, prototyp, název |
| class_defs | Definice tříd: příznaky, superclass, rozhraní, offsety dat |
| data | Skutečná data: kód metod, anotace, informace pro ladění |
Magické číslo DEX — `dex\n035\0` (verze 035). Další verze: 036, 037, 038 (pro Android 8.0+). Hlavička o velikosti 0x70 bajtů obsahuje SHA-1 kontrolní součet a offsety všech sekcí. Validace hlavičky — první krok při načítání DEX virtuálním strojem.
string_ids, type_ids, proto_ids, field_ids, method_ids — jsou indexované tabulky. Místo ukládání plných názvů v kódu metody se používá 4bajtový index. To je klíčová optimalizace: pokud je třída zmíněna 100krát, její název je uložen jednou v string_ids. dex2oat při kompilaci ART tyto tabulky dále optimalizuje.
Proces přeměny zdrojového kódu do DEX se skládá z několika fází. Moderní řetězec používá kompilátor D8, který nahradil DX v roce 2018 s Android Gradle Plugin 3.2.
javac (pro Java) nebo kotlinc (pro Kotlin) kompilují zdrojový kód do souborů .class. Každá třída — samostatný soubor .class v Java bytekódu. V této fázi se provádí kontrola typů, generování bridge metod a vkládání konstant.
D8 přijímá všechny soubory .class a převádí je do DEX bytekódu. D8 provádí několik optimalizací: odstraňuje nepoužívané argumenty metod, slučuje konstantní fondy z různých .class do jednoho globálního fondu DEX, převádí zásobníkové instrukce JVM na registrové instrukce Dalvik.
// Zdrojový kód Kotlin
data class User(
val name: String,
val email: String
)
fun greet(user: User): String {
return "Hello, ${user.name}!"
}
Po kompilaci D8 se tento kód mění v kompaktní instrukce DEX: const-string pro načtení řetězce, iget-object pro přístup k poli objektu, invoke-virtual pro volání StringBuilder.append.
D8 pracuje 2–3krát rychleji než DX, generuje kompaktnější DEX (o 5–10%) a lépe optimalizuje konstrukce specifické pro Kotlin (inline funkce, lambda). DX byl označen jako deprecated od roku 2018 a odstraněn z Android Gradle Plugin 8.0.
Spouštění kódu DEX v Androidu prošlo dvěma fázemi: původní virtuální stroj Dalvik (Android 2.2–4.4) a Android Runtime ART (Android 5.0+). Rozdíl v přístupu ke kompilaci je zásadní.
Dalvik používal Just-In-Time (JIT) kompilaci: DEX bytekód byl interpretován a často volané metody byly kompilovány do nativního kódu za běhu. Výhoda — rychlá instalace. Nevýhoda — pomalejší spouštění a stálé zatížení CPU kvůli JIT.
ART (Android Runtime) kompiluje DEX do nativního kódu při instalaci aplikace prostřednictvím dex2oat. Toto je Ahead-Of-Time (AOT) přístup: instalace trvá déle, ale spouštění je rychlejší a spotřeba energie nižší. Od Android 7.0 ART používá hybridní přístup — AOT + JIT + Profile Guided Optimization.
Nástroj dex2oat se spouští při instalaci nebo aktualizaci aplikace. Kompiluje DEX do souboru ELF s nativním kódem pro architekturu zařízení. Výsledek — soubory .oat a .art v adresáři /data/dalvik-cache/. Google neustále vylepšuje dex2oat: v Android 14 byla přidána optimalizace pro skládací zařízení.
Omezení na 65536 metod na jeden soubor DEX — dědictví z architektury Dalvik. Pole method_ids v hlavičce DEX zabírá 4 bajty, což poskytuje maximálně 2^16 = 65536 jedinečných odkazů. Moderní aplikace s Google Play Services, Firebase a dalšími SDK tento limit snadno překračují.
Multidex je mechanismus rozdělení kódu do více souborů DEX. Hlavní classes.dex obsahuje vstupní body (třídu Application, hlavní Activity), ostatní — classes2.dex, classes3.dex a tak dále. Při spuštění jsou třídy z dalších DEX načítány pomocí DexClassLoader.
// build.gradle.kts — povolení multidex
android {
defaultConfig {
multiDexEnabled = true
}
}
// Třída Application s podporou multidex
class MyApp : Application() {
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
MultiDex.install(this)
}
}
Načítání dalších DEX ve fázi spouštění aplikace může způsobit ANR (Application Not Responding) na zařízeních s Androidem do 5.0. Doporučení — používejte multidex pouze v případě nutnosti a minimalizujte závislosti, abyste nepřekročili limit.
Optimalizace DEX — standardní fáze sestavení release verze aplikace pro Android. Nástroje R8 a ProGuard zmenšují velikost DEX, obfuskovávají kód a odstraňují nepoužívané třídy.
R8 — nástupce ProGuardu, vestavěný do Android Gradle Plugin od roku 2019. R8 provádí minifikaci, obfuskaci a optimalizaci v jednom průchodu, zatímco ProGuard vyžadoval dvě fáze: ProGuard → D8. ProGuard je stále podporován, ale Google doporučuje R8 pro nové projekty.
R8 odstraňuje nepoužívané třídy, metody a pole, přejmenovává je na krátké názvy (a, b, c), vkládá inline funkce a vyhazuje mrtvý kód. Výsledek — DEX se zmenší o 20–40% bez ztráty funkcionality.
Konfigurace R8 se zadává v souboru proguard-rules.pro. Vývojář může určit, které třídy nelze přejmenovat (například pro reflexi nebo serializaci Gson). Firebase a další SDK poskytují vlastní pravidla ve svých závislostech.
DEX lze dekompilovat zpět do Java kódu. To je klíčový bezpečnostní problém aplikací pro Android: bez obfuskace je kód obnoven do úrovně blízké originálu.
JADX — nejpopulárnější dekompilátor DEX do Javy. Obnovuje názvy tříd, metod, polí a většinu logiky. apktool dekompiluje DEX do kódu smali (assembler Dalvik) — nízkoúrovňovou reprezentaci blízkou původním instrukcím. Bytecode Viewer spojuje několik dekompilátorů v jednom rozhraní.
Obfuskace R8/ProGuard — první linie obrany: názvy tříd a metod se stávají nečitelnými. DexGuard — komerční nástroj s dalšími metodami: šifrování řetězců, kontrola integrity, anti-tamper. Obfuskace na úrovni Control Flow (O-LLVM) mění strukturu kódu, zachovává jeho funkčnost, ale značně ztěžuje analýzu.
Často kladené otázky
DEX používá registrovou architekturu místo zásobníkové JVM, má kompaktnější formát (o 30% menší), spojuje všechny .class soubory do jednoho souboru s jednotným konstantním fondem a používá 16bitové indexy místo 8bitových.
Smali — je assembler DEX bytekódu. Každá instrukce DEX má textovou reprezentaci ve formátu smali. Nástroj baksmali převádí DEX do smali (disassemblace) a smali sestavuje smali zpět do DEX.
Gradle úloha countMethods nebo plugin dex-method-counts zobrazují počet metod v každém souboru DEX. Příkaz adb shell s dumpsys také zobrazuje statistiky načtených DEX pro nainstalované aplikace.
Ano, na zařízeních s Androidem do 8.0 vícenásobný DEX zpomaluje spouštění aplikace, protože každý další soubor se načítá samostatně. Na ART s Android 8.0+ je rozdíl minimální díky kompilaci dex2oat do jednoho souboru .oat.
Ano, existují projekty jako dexplorer a implementace JVM kompatibilní s Androidem, které mohou spouštět DEX bytekód mimo Android. Většina souborů DEX však používá Android API, což je činí nevhodnými pro spuštění na běžné JVM.
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é