DEX (Dalvik Executable), Java ve Kotlin ile yazılmış Android uygulamalarının kaynak kodunun derlendiği bir bayt kodu formatıdır. DEX dosyaları, Dalvik sanal makinesi (Android 4.4'e kadar) veya Android Runtime (ART, Android 5.0'den itibaren) tarafından yürütülür. Android Open Source Project, 2026'ya göre, DEX formatı standart JVM Java bayt koduna kıyasla ortalama %30 daha kompakt kod sunar.
Önemli Noktalar
DEX (Dalvik Executable), özellikle Android mobil cihazlar için tasarlanmış bir bayt kodu formatıdır. Standart Java bayt kodundan (.class dosyaları) farklı olarak DEX, sınırlı kaynaklar için optimize edilmiştir: daha az bellek, daha küçük boyut ve daha hızlı sınıf yükleme.
Java veya Kotlin dilindeki kaynak kod, javac/kotlinc tarafından standart .class dosyalarına (Java bayt kodu) derlenir. Ardından d8 aracı (veya daha önce dx) .class dosyalarını bir veya daha fazla DEX dosyasına dönüştürür. Bu dönüşüm basit bir yeniden paketleme değildir — d8 optimizasyonlar gerçekleştirir: sabit havuzlarını birleştirme, talimatları kayıt mimarisine yeniden yazma ve yinelenen verileri kaldırma.
DEX, kayıt tabanlı bir mimari kullanır (yığın tabanlı JVM'nin aksine). Her yöntemin sabit sayıda kaydı vardır (65536'ya kadar). DEX talimatları daha kısadır — ortalama 2 bayt (JVM'de 1–4 bayta karşılık). Bu, daha kompakt kod üretir: tipik bir uygulama 10–15 MB .class'tan 4–6 MB .dex'e düşer.
Bir DEX dosyasının kesin olarak tanımlanmış bir ikili yapısı vardır. Her dosya bir başlıkla başlar ve ofsetler aracılığıyla birbirine referans veren birden çok bölüm içerir.
| Bölüm | Amaç |
|---|---|
| header | Başlık: magic, sağlama toplamı, imza, bölüm boyutları ve ofsetler |
| string_ids | Dize tablosu: sınıf, yöntem ve alan adları |
| type_ids | Türler: tür dize tanımlayıcılarına referanslar |
| proto_ids | Yöntem prototipleri: dönüş türü ve parametreler |
| field_ids | Sınıf alanları: sınıf, tür, ad |
| method_ids | Yöntemler: sınıf, prototip, ad |
| class_defs | Sınıf tanımları: bayraklar, üst sınıf, arayüzler, veri ofsetleri |
| data | Gerçek veriler: yöntem kodu, ek açıklamalar, hata ayıklama bilgileri |
DEX'in sihirli numarası `dex\n035\0` (sürüm 035) şeklindedir. Diğer sürümler: 036, 037, 038 (Android 8.0+ için). Başlık 0x70 bayt boyutundadır ve bir SHA-1 sağlama toplamı ile tüm bölümlerin ofsetlerini içerir. Sanal makine bir DEX yüklerken ilk adım başlık doğrulamasıdır.
string_ids, type_ids, proto_ids, field_ids, method_ids — bunlar indekslenmiş tablolardır. Yöntem kodunda tam adları saklamak yerine 4 baytlık bir indeks kullanılır. Bu önemli bir optimizasyondur: bir sınıf 100 kez referans alınırsa, adı string_ids'te bir kez saklanır. dex2oat, ART derlemesi sırasında bu tabloları daha da optimize eder.
Kaynak kodunu DEX'e dönüştürme süreci birkaç aşamadan oluşur. Modern araç zinciri, 2018'de Android Gradle Plugin 3.2 ile DX'in yerini alan D8 derleyicisini kullanır.
javac (Java için) veya kotlinc (Kotlin için), kaynak kodu .class dosyalarına derler. Her sınıf, Java bayt kodunda ayrı bir .class dosyasıdır. Bu aşamada tür denetimi, köprü yöntem oluşturma ve sabit içerme gerçekleştirilir.
D8, tüm .class dosyalarını alır ve bunları DEX bayt koduna dönüştürür. D8 birkaç optimizasyon gerçekleştirir: kullanılmayan yöntem argümanlarını kaldırma, farklı .class dosyalarındaki sabit havuzlarını tek bir küresel DEX havuzunda birleştirme ve JVM yığın talimatlarını Dalvik kayıt talimatlarına dönüştürme.
// Kotlin kaynak kodu
data class User(
val name: String,
val email: String
)
fun greet(user: User): String {
return "Hello, ${user.name}!"
}
D8 derlemesinden sonra bu kod, kompakt DEX talimatlarına dönüşür: dizeleri yüklemek için const-string, nesne alanına erişmek için iget-object, StringBuilder.append'i çağırmak için invoke-virtual.
D8, DX'ten 2–3 kat daha hızlıdır, daha kompakt DEX üretir (%5–10 daha küçük) ve Kotlin'e özgü yapıları (inline fonksiyonlar, lambda) daha iyi optimize eder. DX, 2018'de kullanımdan kaldırıldı ve Android Gradle Plugin 8.0'den kaldırıldı.
Android'de DEX kodunun yürütülmesi iki aşamadan geçti: orijinal Dalvik sanal makinesi (Android 2.2–4.4) ve Android Runtime ART (Android 5.0+). Derleme yaklaşımındaki fark temeldir.
Dalvik, Just-In-Time (JIT) derlemesi kullanıyordu: DEX bayt kodu yorumlanır ve sık çağrılan yöntemler anında yerel koda derlenirdi. Avantaj — hızlı kurulum. Dezavantaj — daha yavaş başlatma ve JIT için sürekli CPU tüketimi.
ART (Android Runtime), uygulama kurulumu sırasında dex2oat aracılığıyla DEX'i yerel koda derler. Bu bir Ahead-Of-Time (AOT) yaklaşımıdır: kurulum daha uzun sürer, ancak başlatma daha hızlı ve güç tüketimi daha düşüktür. Android 7.0'dan itibaren ART, hibrit bir yaklaşım kullanır — AOT + JIT + Profil Güdümlü Optimizasyon.
dex2oat aracı, bir uygulama kurulduğunda veya güncellendiğinde çalışır. DEX'i cihaz mimarisi için yerel kod içeren bir ELF dosyasına derler. Sonuç — /data/dalvik-cache/ dizininde .oat ve .art dosyaları. Google, dex2oat'ı sürekli olarak iyileştirmektedir: Android 14'te katlanabilir cihazlar için optimizasyonlar eklendi.
DEX dosyası başına 65536 yöntem sınırı, Dalvik mimarisinin bir mirasıdır. DEX başlığındaki method_ids alanı 4 bayt kaplar ve maksimum 2^16 = 65536 benzersiz referans sağlar. Google Play Services, Firebase ve diğer SDK'lara sahip modern uygulamalar bu sınırı kolayca aşar.
Multidex, kodu birden çok DEX dosyasına bölmek için bir mekanizmadır. Ana classes.dex, giriş noktalarını (Application sınıfı, ana Activity) içerir, diğerleri classes2.dex, classes3.dex vb. şeklindedir. Başlatma sırasında, ek DEX'lerdeki sınıflar DexClassLoader aracılığıyla yüklenir.
// build.gradle.kts — multidex etkinleştirme
android {
defaultConfig {
multiDexEnabled = true
}
}
// Multidex desteği ile Application sınıfı
class MyApp : Application() {
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
MultiDex.install(this)
}
}
Uygulama başlatma sırasında ek DEX'lerin yüklenmesi, Android 5.0 öncesi cihazlarda ANR'ye (Application Not Responding) neden olabilir. Öneri — yalnızca gerektiğinde multidex kullanın ve sınırı aşmamak için bağımlılıkları en aza indirin.
DEX optimizasyonu, bir sürüm Android uygulaması oluşturmanın standart bir adımıdır. R8 ve ProGuard araçları DEX boyutunu azaltır, kodu karartır ve kullanılmayan sınıfları kaldırır.
R8, ProGuard'ın halefidir, 2019'dan beri Android Gradle Plugin'e yerleşiktir. R8, tek geçişte küçültme, karartma ve optimizasyon gerçekleştirirken, ProGuard iki aşama gerektiriyordu: ProGuard → D8. ProGuard hâlâ desteklenmektedir, ancak Google yeni projeler için R8'i önermektedir.
R8, kullanılmayan sınıfları, yöntemleri ve alanları kaldırır, bunları kısa adlarla (a, b, c) yeniden adlandırır, işlev içi yöntemleri ekler ve ölü kodu kaldırır. Sonuç — işlevsellik kaybı olmadan DEX %20–40 oranında küçülür.
R8 yapılandırması proguard-rules.pro dosyasında belirtilir. Geliştirici, hangi sınıfların yeniden adlandırılamayacağını belirtebilir (örneğin, yansıma veya Gson serileştirmesi için). Firebase ve diğer SDK'lar, bağımlılıklarında kendi kurallarını sağlar.
DEX, Java koduna geri tersine derlenebilir. Bu, Android uygulamaları için önemli bir güvenlik sorunudur: karartma olmadan, kod orijinaline yakın bir düzeyde geri yüklenir.
JADX, en popüler DEX'ten Java'ya tersine derleyicidir. Sınıf adlarını, yöntemleri, alanları ve mantığın çoğunu geri yükler. apktool, DEX'i smali koduna (Dalvik assembler) tersine derler — orijinal talimatlara yakın düşük seviyeli bir temsil. Bytecode Viewer, birden çok tersine derleyiciyi tek bir arayüzde birleştirir.
R8/ProGuard ile karartma ilk savunma hattıdır: sınıf ve yöntem adları okunamaz hale gelir. DexGuard, ek yöntemlere sahip ticari bir araçtır: dize şifreleme, bütünlük denetimi, kurcalama önleme. Kontrol Akışı Karartması (O-LLVM), işlevselliği korurken kod yapısını değiştirir ve analizi çok daha zor hale getirir.
Sıkça Sorulan Sorular
DEX, yığın tabanlı JVM yerine kayıt tabanlı bir mimari kullanır, daha kompakt bir formata (%30 daha küçük) sahiptir, tüm .class dosyalarını tek bir sabit havuzuyla tek bir dosyada birleştirir ve 8 bit yerine 16 bit indeksler kullanır.
Smali, DEX bayt kodu için bir assemblerdir. Her DEX talimatının smali formatında bir metin temsili vardır. baksmali aracı DEX'i smali'ye dönüştürür (disassembling) ve smali, smali'yi tekrar DEX'e assemble eder.
Gradle countMethods görevi veya dex-method-counts eklentisi, her DEX dosyasındaki yöntem sayısını gösterir. adb shell komutu dumpsys ile birlikte yüklü uygulamalar için yüklenen DEX'lerin istatistiklerini de görüntüler.
Evet, Android 8.0 öncesi cihazlarda birden çok DEX dosyası uygulama başlatmayı yavaşlatır çünkü her ek dosya ayrı ayrı yüklenir. Android 8.0+ ile ART'de, dex2oat derlemesinin tek bir .oat dosyasına yapılması sayesinde fark minimumdur.
Evet, dexplorer ve Android uyumlu JVM uygulamaları gibi projeler, DEX bayt kodunu Android dışında çalıştırabilir. Ancak çoğu DEX dosyası Android API'sini kullanır ve bu da onları standart bir JVM'de çalıştırmak için uygunsuz hale getirir.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun