DEX (Dalvik Executable) — Java və Kotlin-də Android tətbiqlərinin mənbə kodunun kompilyasiya olunduğu bayt-kod formatıdır. DEX faylları Dalvik virtual maşını (Android 4.4-dək) və ya Android Runtime (ART, Android 5.0-dan etibarən) tərəfindən icra olunur. Android Open Source Project, 2026 məlumatlarına görə, DEX formatı standart JVM bayt-kodu ilə müqayisədə orta hesabla 30% daha yığcam kod təqdim edir.
Əsas məqamlar
DEX (Dalvik Executable) — xüsusi olaraq Android mobil cihazları üçün hazırlanmış bayt-kod formatıdır. Standart Java bayt-kodundan (.class faylları) fərqli olaraq, DEX məhdud resurslar üçün optimallaşdırılıb: az yaddaş, kiçik ölçü və daha sürətli sinif yükləmə.
Java və ya Kotlin-də mənbə kodu javac/kotlinc tərəfindən standart .class fayllarına (Java bayt-kodu) kompilyasiya olunur. Sonra d8 aləti (və ya əvvəllər dx) .class fayllarını bir və ya bir neçə DEX faylına çevirir. Bu çevirmə sadə qablaşdırma deyil — d8 optimallaşdırmalar həyata keçirir: sabit hovuzlarını birləşdirir, təlimatları registr arxitekturasına yazır və təkrarlanan məlumatları silir.
DEX registr arxitekturasından istifadə edir (JVM-in yığın arxitekturasından fərqli olaraq). Hər metodun sabit sayda registri var (65536-dək). DEX təlimatları daha qısadır — orta hesabla 2 bayt, JVM-də isə 1–4 bayt. Bu daha yığcam kod verir: tipik tətbiq 10–15 MB .class-dan 4–6 MB .dex-ə qədər azalır.
DEX faylı ciddi şəkildə müəyyən edilmiş ikili struktura malikdir. Hər fayl başlıqla başlayır və bir-birinə ofsetlər vasitəsilə istinad edən bir neçə bölmə ehtiva edir.
| Bölmə | Məqsəd |
|---|---|
| header | Başlıq: magic, yoxlama məbləği, imza, bölmələrin ölçüləri və ofsetləri |
| string_ids | Sətir cədvəli: sinif, metod, sahə adları |
| type_ids | Növlər: tip sətir identifikatorlarına istinadlar |
| proto_ids | Metod prototipləri: qaytarılan tip və parametrlər |
| field_ids | Sinif sahələri: sinif, tip, ad |
| method_ids | Metodlar: sinif, prototip, ad |
| class_defs | Sinif tərifləri: bayraqlar, superclass, interfeyslər, məlumat ofsetləri |
| data | Faktiki məlumatlar: metod kodu, annotasiyalar, debug məlumatı |
Sehrli DEX ədədi — `dex\n035\0` (versiya 035). Digər versiyalar: 036, 037, 038 (Android 8.0+ üçün). 0x70 bayt ölçüsündə başlıq SHA-1 yoxlama məbləği və bütün bölmələrin ofsetlərini ehtiva edir. Başlığın validasiyası — virtual maşın tərəfindən DEX yüklənərkən ilk addımdır.
string_ids, type_ids, proto_ids, field_ids, method_ids — indeksləşdirilmiş cədvəllərdir. Metod kodunda tam adların saxlanması əvəzinə 4-baytlı indeks istifadə olunur. Bu əsas optimallaşdırmadır: sinif 100 dəfə qeyd olunursa, onun adı string_ids-də bir dəfə saxlanılır. dex2oat ART kompilyasiyası zamanı bu cədvəlləri əlavə optimallaşdırır.
Proses mənbə kodunun DEX-ə çevrilməsi bir neçə mərhələdən ibarətdir. Müasir zəncir 2018-ci ildə Android Gradle Plugin 3.2 ilə DX-i əvəz edən D8 kompilyatorundan istifadə edir.
javac (Java üçün) və ya kotlinc (Kotlin üçün) mənbə kodunu .class fayllarına kompilyasiya edir. Hər sinif — Java bayt-kodunda ayrıca .class faylı. Bu mərhələdə tip yoxlaması, körpü metodlarının yaradılması və sabitlərin yerləşdirilməsi həyata keçirilir.
D8 bütün .class fayllarını qəbul edir və onları DEX bayt-koduna çevirir. D8 bir neçə optimallaşdırma həyata keçirir: istifadə olunmayan metod arqumentlərini silir, müxtəlif .class fayllarından sabit hovuzlarını bir qlobal DEX hovuzunda birləşdirir, JVM yığın təlimatlarını Dalvik registr təlimatlarına çevirir.
// Kotlin mənbə kodu
data class User(
val name: String,
val email: String
)
fun greet(user: User): String {
return "Hello, ${user.name}!"
}
D8 kompilyasiyasından sonra bu kod yığcam DEX təlimatlarına çevrilir: sətir yükləmək üçün const-string, obyekt sahəsinə daxil olmaq üçün iget-object, StringBuilder.append çağırmaq üçün invoke-virtual.
D8 DX-dən 2–3 dəfə sürətli işləyir, daha yığcam DEX yaradır (5–10%) və Kotlin-spesifik konstruksiyaları (inline funksiyalar, lambda) daha yaxşı optimallaşdırır. DX 2018-ci ildən deprecated elan edilib və Android Gradle Plugin 8.0-dan silinib.
DEX kodunun Android-də icrası iki mərhələdən keçib: orijinal Dalvik virtual maşını (Android 2.2–4.4) və Android Runtime ART (Android 5.0+). Kompilyasiya yanaşmasında fərq köklüdür.
Dalvik Just-In-Time (JIT) kompilyasiyasından istifadə edirdi: DEX bayt-kodu interpretasiya olunur, tez-tez çağırılan metodlar isə nativ koda anında kompilyasiya edilirdi. Üstünlük — sürətli quraşdırma. Çatışmazlıq — daha yavaş başlanğıc və JIT üçün daimi CPU yükü.
ART (Android Runtime) tətbiq quraşdırılması zamanı dex2oat vasitəsilə DEX-i nativ koda kompilyasiya edir. Bu Ahead-Of-Time (AOT) yanaşmasıdır: quraşdırma uzun çəkir, lakin başlanğıc daha sürətli və enerji sərfiyyatı azdır. Android 7.0-dan ART hibrid yanaşma — AOT + JIT + Profile Guided Optimization istifadə edir.
dex2oat aləti tətbiq quraşdırılması və ya yenilənməsi zamanı işə düşür. O, DEX-i cihaz arxitekturası üçün nativ kodla ELF faylına kompilyasiya edir. Nəticə — /data/dalvik-cache/ qovluğunda .oat və .art faylları. Google dex2oat-ı daim təkmilləşdirir: Android 14-də qatlanan cihazlar üçün optimallaşdırma əlavə edilib.
Bir DEX faylında 65536 metod məhdudiyyəti — Dalvik arxitekturasından qalma mirasdır. DEX başlığında method_ids sahəsi 4 bayt tutur, bu da maksimum 2^16 = 65536 unikal istinad verir. Google Play Services, Firebase və digər SDK-ları olan müasir tətbiqlər bu limiti asanlıqla keçir.
Multidex — kodun bir neçə DEX faylına bölünməsi mexanizmidir. Əsas classes.dex giriş nöqtələrini (Application sinifi, əsas Activity) ehtiva edir, qalanları — classes2.dex, classes3.dex və s. İşə salınma zamanı əlavə DEX-lərdən siniflər DexClassLoader vasitəsilə yüklənir.
// build.gradle.kts — multidex-in qoşulması
android {
defaultConfig {
multiDexEnabled = true
}
}
// Multidex dəstəyi ilə Application sinifi
class MyApp : Application() {
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
MultiDex.install(this)
}
}
Əlavə DEX-lərin tətbiq startı mərhələsində yüklənməsi Android 5.0-dək cihazlarda ANR (Application Not Responding) səbəb ola bilər. Tövsiyə — multidex-i yalnız zəruri olduqda istifadə edin və limiti keçməmək üçün asılılıqları minimallaşdırın.
DEX optimallaşdırması — release Android tətbiqi qurulmasının standart mərhələsidir. R8 və ProGuard alətləri DEX ölçüsünü azaldır, kodu obfuskiasiya edir və istifadə olunmayan sinifləri silir.
R8 — ProGuard-ın varisi, 2019-cu ildən Android Gradle Plugin-ə daxildir. R8 minifikasiya, obfuskasiya və optimallaşdırmanı bir keçiddə yerinə yetirir, ProGuard isə iki mərhələ tələb edirdi: ProGuard → D8. ProGuard hələ də dəstəklənir, lakin Google yeni layihələr üçün R8-i tövsiyə edir.
R8 istifadə olunmayan sinifləri, metodları və sahələri silir, onların adlarını qısa adlarla (a, b, c) əvəz edir, inline funksiyaları yerləşdirir və ölü kodu atır. Nəticə — DEX funksionallığı itirmədən 20–40% azalır.
R8 konfiqurasiyası proguard-rules.pro faylında verilir. Tərtibatçı hansı siniflərin adlarının dəyişdirilməməsini göstərə bilər (məsələn, refleksiya və ya Gson seriyalaşdırması üçün). Firebase və digər SDK-lar öz asılılıqlarında öz qaydalarını təqdim edir.
DEX geri Java koduna dekompilyasiya oluna bilər. Bu Android tətbiqlərinin təhlükəsizliyinin əsas məsələsidir: obfuskasiya olmadan kod orijinala yaxın səviyyədə bərpa olunur.
JADX — DEX-in Java-ya ən məşhur dekompilyatoru. Sinif adlarını, metodları, sahələri və logikanın çox hissəsini bərpa edir. apktool DEX-i smali koduna (Dalvik assembler) dekompilyasiya edir — orijinal təlimatlara yaxın aşağı səviyyəli təsvir. Bytecode Viewer bir neçə dekompilyatoru bir interfeysdə birləşdirir.
R8/ProGuard obfuskasiyası — ilk müdafiə xətti: sinif və metod adları oxunmaz olur. DexGuard — əlavə metodlarla kommersiya aləti: sətir şifrələmə, bütövlük yoxlaması, anti-tamper. Control Flow səviyyəsində obfuskasiya (O-LLVM) kodun strukturunu dəyişir, funksionallığı saxlayır, lakin analizi xeyli çətinləşdirir.
Tez-tez verilən suallar
DEX JVM-in yığın arxitekturası əvəzinə registr arxitekturasından istifadə edir, daha yığcam formatdadır (30% kiçik), bütün .class fayllarını vahid sabit hovuzu olan bir faylda birləşdirir və 8-bit əvəzinə 16-bit indekslərdən istifadə edir.
Smali — DEX bayt-kodunun assembleridir. Hər DEX təlimatının smali formatında mətn təsviri var. baksmali aləti DEX-i smali-yə çevirir (dezasembllama), smali isə smali-ni geri DEX-ə yığır.
Gradle countMethods tapşırığı və ya dex-method-counts plagini hər DEX faylında metodların sayını göstərir. adb shell əmri dumpsys ilə də quraşdırılmış tətbiqlər üçün yüklənmiş DEX-lərin statistikasını göstərir.
Bəli, Android 8.0-dək cihazlarda çoxsaylı DEX tətbiqin başlanğıcını yavaşladır, çünki hər əlavə fayl ayrıca yüklənir. Android 8.0+ ilə ART-də fərq minimaldır, çünki dex2oat vahid .oat faylına kompilyasiya edir.
Bəli, dexplorer və Android-uyğun JVM tətbiqləri kimi layihələr DEX bayt-kodunu Android xaricində icra edə bilər. Lakin əksər DEX faylları Android API-dən istifadə edir, bu da onları adi JVM-də işə salmaq üçün yararsız edir.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun