DEX: ما هو، الهيكل ومبدأ عمل البايت كود

المؤلف: IT Sectr نُشر: 2026-04-15 وقت القراءة: 8 دق

DEX (Dalvik Executable) هو تنسيق بايت كود يتم ترجمة الكود المصدري لتطبيقات Android بلغة Java وKotlin إليه. يتم تنفيذ ملفات DEX بواسطة الآلة الافتراضية Dalvik (حتى Android 4.4) أو Android Runtime (ART، بدءاً من Android 5.0). وفقاً لـ Android Open Source Project، 2026، يوفر تنسيق DEX في المتوسط 30% تمثيلاً أكثر ضغطاً للكود مقارنة ببايت كود JVM القياسي.

أهم النقاط

  • DEX هو تنسيق بايت كود لنظام Android، يتم تنفيذه على Dalvik أو ART.
  • الضغط — يشغل DEX مساحة أقل بنسبة 30% من بايت كود Java القياسي.
  • Multidex — آلية لتجاوز حد 65536 طريقة في ملف DEX واحد.
  • ART — Android Runtime، الذي حل محل Dalvik، يترجم DEX إلى كود أصلي أثناء التثبيت.
  • D8 — مترجم حديث من Java/Kotlin إلى DEX، حل محل DX منذ 2018.

ما هو DEX ولماذا هو مطلوب

DEX (Dalvik Executable) هو تنسيق بايت كود مصمم خصيصاً للأجهزة المحمولة التي تعمل بنظام Android. على عكس بايت كود Java القياسي (ملفات .class)، تم تحسين DEX للموارد المحدودة: ذاكرة أقل، حجم أصغر، وتحميل أسرع للفئات.

من Java إلى DEX

يتم ترجمة الكود المصدري بلغة Java أو Kotlin بواسطة javac/kotlinc إلى ملفات .class القياسية (بايت كود Java). ثم تقوم أداة d8 (أو dx سابقاً) بتحويل .class إلى ملف DEX واحد أو أكثر. هذا التحويل ليس مجرد إعادة تغليف — بل يقوم d8 بتحسينات: دمج مجموعات الثوابت، إعادة كتابة التعليمات إلى بنية السجلات، وإزالة البيانات المكررة.

الميزات المعمارية

يستخدم DEX بنية قائمة على السجلات (بعكس JVM القائمة على المكدس). كل طريقة لها عدد ثابت من السجلات (حتى 65536). تعليمات DEX أقصر — في المتوسط 2 بايت مقابل 1–4 بايت في JVM. هذا ينتج كوداً أكثر ضغطاً: يتقلص التطبيق النموذجي من 10–15 ميجابايت من .class إلى 4–6 ميجابايت من .dex.

هيكل ملف DEX: الأقسام والرأس

ملف DEX له بنية ثنائية محددة بدقة. يبدأ كل ملف برأس ويحتوي على عدة أقسام تشير إلى بعضها البعض من خلال الإزاحات.

القسمالغرض
headerالرأس: magic، المجموع الاختباري، التوقيع، أحجام وإزاحات الأقسام
string_idsجدول السلاسل: أسماء الفئات، الطرق، الحقول
type_idsالأنواع: مراجع لمعرفات سلسلة الأنواع
proto_idsنماذج الطرق: نوع الإرجاع والمعاملات
field_idsحقول الفئات: الفئة، النوع، الاسم
method_idsالطرق: الفئة، النموذج، الاسم
class_defsتعريفات الفئات: العلامات، الفئة الأم، الواجهات، إزاحات البيانات
dataالبيانات الفعلية: كود الطرق، التعليقات التوضيحية، معلومات التصحيح

رأس DEX

الرقم السحري لـ DEX هو `dex\n035\0` (الإصدار 035). إصدارات أخرى: 036، 037، 038 (لـ Android 8.0+). الرأس بحجم 0x70 بايت ويحتوي على المجموع الاختباري SHA-1 وإزاحات جميع الأقسام. التحقق من صحة الرأس هو الخطوة الأولى عند تحميل DEX بواسطة الآلة الافتراضية.

مجموعات الثوابت

string_ids، type_ids، proto_ids، field_ids، method_ids — هي جداول مفهرسة. بدلاً من تخزين الأسماء الكاملة في كود الطريقة، يتم استخدام فهرس 4 بايت. هذا تحسين رئيسي: إذا تم ذكر فئة 100 مرة، يتم تخزين اسمها مرة واحدة في string_ids. dex2oat يحسن هذه الجداول بشكل إضافي أثناء ترجمة ART.

عملية ترجمة Java وKotlin إلى DEX

عملية تحويل الكود المصدري إلى DEX تتكون من عدة مراحل. سلسلة الأدوات الحديثة تستخدم المترجم D8، الذي حل محل DX في 2018 مع Android Gradle Plugin 3.2.

المرحلة 1: الترجمة إلى .class

javac (لـ Java) أو kotlinc (لـ Kotlin) يترجمان الكود المصدري إلى ملفات .class. كل فئة هي ملف .class منفصل في بايت كود Java. في هذه المرحلة، يتم التحقق من الأنواع، إنشاء طرق bridge، وتضمين الثوابت.

المرحلة 2: ترجمة D8

D8 يأخذ جميع ملفات .class ويحولها إلى بايت كود DEX. يقوم D8 بعدة تحسينات: يزيل وسائط الطرق غير المستخدمة، يدمج مجموعات الثوابت من ملفات .class المختلفة في مجموعة واحدة عالمية لـ DEX، ويحول تعليمات مكدس JVM إلى تعليمات سجلات Dalvik.

kotlin
// كود مصدر Kotlin
data class User(
    val name: String,
    val email: String
)

fun greet(user: User): String {
    return "Hello, ${user.name}!"
}

بعد ترجمة D8، يتحول هذا الكود إلى تعليمات DEX مضغوطة: const-string لتحميل السلاسل، iget-object للوصول إلى حقل الكائن، invoke-virtual لاستدعاء StringBuilder.append.

D8 مقابل DX

D8 أسرع من DX بمقدار 2–3 مرات، وينتج DEX أكثر ضغطاً (أصغر بنسبة 5–10%)، ويحسن بشكل أفضل التركيبات الخاصة بـ Kotlin (الدوال المضمنة، lambdas). تم إعلان DX قديماً في 2018 وتمت إزالته من Android Gradle Plugin 8.0.

Dalvik vs ART: كيف تغير تنفيذ DEX

تنفيذ كود DEX في Android مر بمرحلتين: الآلة الافتراضية Dalvik الأصلية (Android 2.2–4.4) وAndroid Runtime ART (Android 5.0+). الفرق في نهج الترجمة جوهري.

Dalvik VM: ترجمة JIT

Dalvik استخدمت الترجمة في الوقت المناسب (JIT): يتم تفسير بايت كود DEX، ويتم ترجمة الطرق التي يتم استدعاؤها بشكل متكرر إلى كود أصلي أثناء التشغيل. الإيجابيات — تثبيت سريع. السلبيات — بدء أبطأ واستهلاك مستمر لوحدة المعالجة المركزية لـ JIT.

ART: ترجمة AOT

ART (Android Runtime) يقوم بترجمة DEX إلى كود أصلي أثناء تثبيت التطبيق عبر dex2oat. هذا نهج Ahead-Of-Time (AOT): التثبيت أطول، لكن البدء أسرع واستهلاك الطاقة أقل. منذ Android 7.0، يستخدم ART نهجاً هجيناً — AOT + JIT + Profile Guided Optimization.

dex2oat: التحويل أثناء التثبيت

أداة dex2oat تعمل عند تثبيت أو تحديث التطبيق. تقوم بترجمة DEX إلى ملف ELF مع كود أصلي لبنية الجهاز. النتيجة — ملفات .oat و .art في دليل /data/dalvik-cache/. Google تحسن dex2oat باستمرار: على Android 14 تمت إضافة تحسينات للأجهزة القابلة للطي.

Multidex: تجاوز حد 64K طريقة

حد 65536 طريقة لكل ملف DEX هو إرث من بنية Dalvik. حقل method_ids في رأس DEX يشغل 4 بايت، مما يعطي حداً أقصى 2^16 = 65536 مرجعاً فريداً. التطبيقات الحديثة مع Google Play Services وFirebase وSDKs أخرى تتجاوز هذا الحد بسهولة.

آلية Multidex

Multidex هي آلية لتقسيم الكود عبر عدة ملفات DEX. يحتوي classes.dex الرئيسي على نقاط الدخول (فئة Application، النشاط الرئيسي)، والباقي هي classes2.dex وclasses3.dex وهكذا. عند بدء التشغيل، يتم تحميل الفئات من ملفات DEX الإضافية عبر DexClassLoader.

kotlin
// build.gradle.kts — تفعيل multidex
android {
    defaultConfig {
        multiDexEnabled = true
    }
}

// فئة Application مع دعم multidex
class MyApp : Application() {
    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(base)
        MultiDex.install(this)
    }
}

مشاكل Multidex

تحميل ملفات DEX الإضافية أثناء بدء تشغيل التطبيق يمكن أن يسبب ANR (Application Not Responding) على الأجهزة التي تعمل بنظام Android أقل من 5.0. التوصية — استخدام multidex فقط عند الضرورة وتقليل التبعيات لتجنب تجاوز الحد.

تحسين DEX: ProGuard وR8 والتعتيم

تحسين DEX هو خطوة قياسية في بناء تطبيق Android للإصدار. أدوات R8 وProGuard تقلل حجم DEX، وتعتم الكود، وتزيل الفئات غير المستخدمة.

R8 مقابل ProGuard

R8 هو خليفة ProGuard، المدمج في Android Gradle Plugin منذ 2019. يقوم R8 بالتصغير والتعتيم والتحسين في تمريرة واحدة، بينما كان ProGuard يتطلب مرحلتين: ProGuard → D8. ProGuard لا يزال مدعوماً، لكن Google توصي باستخدام R8 للمشاريع الجديدة.

يزيل R8 الفئات والطرق والحقول غير المستخدمة، ويعيد تسميتها بأسماء قصيرة (a، b، c)، ويضمّن الدوال المضمنة ويزيل الكود الميت. النتيجة — يتقلص DEX بنسبة 20–40% دون فقدان الوظائف.

قواعد R8

يتم تحديد تكوين R8 في ملف proguard-rules.pro. يمكن للمطور تحديد الفئات التي لا يمكن إعادة تسميتها (على سبيل المثال، للتفكير التأملي أو تسلسل Gson). Firebase وSDKs أخرى توفر قواعدها الخاصة في تبعياتها.

فك ترجمة DEX: الأدوات والحماية

DEX يمكن فك ترجمته مرة أخرى إلى كود Java. هذه مسألة أمان رئيسية لتطبيقات Android: بدون التعتيم، يتم استعادة الكود إلى مستوى قريب من الأصل.

أدوات فك الترجمة

JADX هو أكثر أدوات فك ترجمة DEX إلى Java شيوعاً. يستعيد أسماء الفئات والطرق والحقول ومعظم المنطق. apktool يفك ترجمة DEX إلى كود smali (مجمّع Dalvik) — تمثيل منخفض المستوى قريب من التعليمات الأصلية. Bytecode Viewer يجمع عدة أدوات فك ترجمة في واجهة واحدة.

طرق الحماية

التعتيم باستخدام R8/ProGuard هو خط الدفاع الأول: تصبح أسماء الفئات والطرق غير قابلة للقراءة. DexGuard أداة تجارية بطرق إضافية: تشفير السلاسل، التحقق من السلامة، مضاد للتلاعب. تعتيم تدفق التحكم (O-LLVM) يغير بنية الكود مع الحفاظ على وظائفه، مما يجعل التحليل أكثر صعوبة.

الأسئلة الشائعة

كيف يختلف DEX عن بايت كود Java؟

DEX يستخدم بنية قائمة على السجلات بدلاً من JVM القائمة على المكدس، وله تنسيق أكثر ضغطاً (أصغر بنسبة 30%)، ويدمج جميع ملفات .class في ملف واحد بمجموعة ثوابت موحدة، ويستخدم فهارس 16 بت بدلاً من 8 بت.

ما هو smali؟

Smali هو مجمّع لبايت كود DEX. كل تعليمة DEX لها تمثيل نصي بتنسيق smali. أداة baksmali تحول DEX إلى smali (فك التجميع)، وsmali يجمع smali مرة أخرى إلى DEX.

كيفية التحقق من عدد الطرق في DEX؟

مهمة Gradle countMethods أو إضافة dex-method-counts تظهر عدد الطرق في كل ملف DEX. أمر adb shell مع dumpsys يعرض أيضاً إحصائيات DEX المحملة للتطبيقات المثبتة.

هل يؤثر عدد ملفات DEX على الأداء؟

نعم، على الأجهزة التي تعمل بنظام Android قبل 8.0، تعدد ملفات DEX يبطئ بدء تشغيل التطبيق لأن كل ملف إضافي يتم تحميله بشكل منفصل. على ART مع Android 8.0+، الفرق ضئيل بفضل ترجمة dex2oat إلى ملف .oat واحد.

هل يمكن تشغيل DEX بدون Android؟

نعم، هناك مشاريع مثل dexplorer وتطبيقات JVM المتوافقة مع Android يمكنها تنفيذ بايت كود DEX خارج Android. ومع ذلك، معظم ملفات DEX تستخدم Android API، مما يجعلها غير مناسبة للتشغيل على JVM قياسي.

الخلاصة

  • DEX هو تنسيق بايت كود Android ببنية قائمة على السجلات وتمثيل مضغوط للكود.
  • الهيكل يتضمن رأساً وجداول معرفات وقسم بيانات مع تعليمات.
  • الترجمة إلى DEX تتم عبر D8: .class → DEX مع تحسينات ودمج مجموعات الثوابت.
  • ART يترجم DEX إلى كود أصلي أثناء التثبيت (AOT)، مما يسرع بدء التطبيق.
  • Multidex يحل مشكلة حد 65536 طريقة عن طريق التقسيم إلى عدة ملفات DEX.
  • التحسين — R8 يقلص DEX بنسبة 20–40%، ويعتم الأسماء ويزيل الكود الميت.
  • الحماية — التعتيم باستخدام R8/ProGuard وDexGuard وO-LLVM يمنع فك ترجمة DEX.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا