פורמט הפעלה מסוג Dalvik

במסמך הזה מתוארים הפריסה והתוכן של קובצי .dex, שמשמשים לאחסון קבוצה של הגדרות של כיתות והנתונים המשניים המשויכים אליהן.

מדריך לסוגי המודעות

שם תיאור
בייט int signed‏ 8-bit
ubyte int לא חתום של 8 ביט
סרטון קצר int signed 16-bit, little-endian
ushort int לא חתום של 16 ביט, little-endian
INT מספר שלם עם סימן באורך 32 ביט, בסדר קטן-גדול
uint int לא חתום של 32 ביט, little-endian
ארוך int signed של 64 ביט, little-endian
ulong int לא חתום של 64 ביט, little-endian
sleb128 LEB128 חתום, באורך משתנה (ראו בהמשך)
uleb128 LEB128 ללא סימן, באורך משתנה (ראו בהמשך)
uleb128p1 LEB128 ללא סימן ו-1, באורך משתנה (ראו בהמשך)

LEB128

LEB128 (‏'Little-Endian Base 128') הוא קידוד באורך משתנה של כמויות שלמים שרירותיים עם סימן או ללא סימן. הפורמט הועתק מהמפרט של DWARF3. בקובץ .dex, LEB128 משמש רק לקידוד כמויות של 32 ביט.

כל ערך בקידוד LEB128 מורכב מבאיט אחד עד חמישה, שמייצגים יחד ערך יחיד של 32 ביט. כל בייט מוגדר לפי הביט המשמעותי ביותר שלו, מלבד הבייט האחרון ברצף, שהביט המשמעותי ביותר שלו לא מוגדר. שבע הביטים הנותרים בכל בייט הם נתוני המטען, כאשר שבע הביטים הפחות משמעותיים של הכמות נמצאים בבייטים הראשון, שבע הביטים הבאים נמצאים בבייטים השני וכן הלאה. במקרה של LEB128 עם סימן (sleb128), ביט המטען המשמעותי ביותר של הבייט האחרון ברצף מורחב עם סימן כדי ליצור את הערך הסופי. במקרה ללא סימן (uleb128), כל הביטים שלא מיוצגים באופן מפורש מפורשים כ-0.

תרשים ביטתי של ערך LEB128 באורך שני בייטים
הבייט הראשון הבייט השני
1 ביט6 bit5 ביט4 ביט3 ביט2 ביט1 ביט0 0 ביט13 bit‏12 ביט11 bit‏10 ביט9 bit8 ביט7

הווריאנט uleb128p1 משמש לייצוג ערך חתום, שבו הייצוג הוא הערך פלוס אחד בקידוד uleb128. כך, קידוד הערך -1 (או הערך ללא סימן 0xffffffff) – אבל לא מספר שלילי אחר – הוא ביייט אחד, והוא שימושי בדיוק במקרים שבהם המספר שמיוצג חייב להיות חיובי או -1 (או 0xffffffff), ושאין ערכים שליליים אחרים שמותר להשתמש בהם (או במקרים שבהם סביר להניח שלא תצטרכו ערכים גדולים ללא סימן).

ריכזנו כאן כמה דוגמאות לפורמטים:

רצף מקודד בתור sleb128 בתור uleb128 בתור uleb128p1
0000-1
01110
7f-1127126
80 7f-1281625616255

פריסת הקובץ

שם פורמט תיאור
כותרת header_item הכותרת
string_ids string_id_item[] רשימת מזהים של מחרוזות. אלה מזהים לכל המחרוזות שבהן הקובץ הזה משתמש, לצורכי שמות פנימיים (למשל, מתארי טיפוסים) או כאובייקטים קבועים שמקודם מפנה אליהם. הרשימה הזו צריכה להיות ממוינת לפי תוכן המחרוזת, באמצעות ערכי נקודות קוד של UTF-16 (לא באופן תלוי-אזור), בלי להכיל רשומות כפולות.
type_ids type_id_item[] רשימת מזהי הסוגים. אלה המזהים של כל הסוגים (כיתות, מערכי נתונים או סוגים פרימיטיביים) שהקובץ הזה מפנה אליהם, בין שהם מוגדרים בקובץ ובין שלא. הרשימה הזו חייבת להיות ממוינת לפי אינדקס string_id, ואי אפשר לכלול בה רשומות כפולות.
proto_ids proto_id_item[] רשימת המזהים של אב טיפוס השיטה. אלה המזהים של כל אב הטיפוס שאליו מתייחס הקובץ הזה. הרשימה הזו צריכה להיות ממוינת לפי סדר ראשי של סוג ההחזרה (לפי אינדקס type_id), ואז לפי רשימת הארגומנטים (מיון לקסיקלי, ארגומנטים נפרדים שממוינים לפי אינדקס type_id). הרשימה לא יכולה לכלול רשומות כפולות.
field_ids field_id_item[] רשימת מזהי השדות. אלה המזהים של כל השדות שאליהם מתייחס הקובץ, בין שהם מוגדרים בקובץ ובין שלא. הרשימה הזו צריכה להיות ממוינת, כאשר הסוג המגדיר (לפי אינדקס type_id) הוא הסדר הראשי, שם השדה (לפי אינדקס string_id) הוא הסדר הביניים והסוג (לפי אינדקס type_id) הוא הסדר המשני. הרשימה לא יכולה לכלול רשומות כפולות.
method_ids method_id_item[] רשימת מזהי השיטות. אלה המזהים של כל השיטות שאל הקובץ הזה מפנה אליהן, בין שהן מוגדרות בקובץ ובין שלא. הרשימה הזו צריכה להיות ממוינת, כאשר הסוג המגדיר (לפי אינדקס type_id) הוא הסדר הראשי, שם method (לפי אינדקס string_id) הוא הסדר הביניים ו-method prototype (לפי אינדקס proto_id) הוא הסדר המשני. הרשימה לא יכולה לכלול רשומות כפולות.
class_defs class_def_item[] רשימת הגדרות הכיתות. הכיתות צריכות להיות מסודרות כך שסופר-הקלאס של הכיתה הנתונה והממשקים המוטמעים שלה יופיעו ברשימה לפני הכיתה המפנה. בנוסף, לא ניתן להגדיר כיתה באותו שם יותר מפעם אחת ברשימה.
call_site_ids call_site_id_item[] רשימת המזהים של אתרי השיחות. אלה המזהים של כל אתרי הקריאה שאליהם מתייחס הקובץ הזה, גם אם הם מוגדרים בקובץ וגם אם לא. הרשימה הזו צריכה להיות ממוינת בסדר עולה של call_site_off.
method_handles method_handle_item[] method מטפלת ברשימה. רשימה של כל רכיבי ה-method handle שאליהם מתייחס הקובץ הזה, גם אם הם מוגדרים בקובץ וגם אם לא. הרשימה הזו לא ממוינת ועשויה להכיל כפילויות שתואמות באופן לוגי למופעים שונים של פקדי שיטות.
נתונים ubyte[] אזור נתונים שמכיל את כל נתוני התמיכה של הטבלאות שצוינו למעלה. לפריטים שונים יש דרישות התאמה שונות, ואפשר להוסיף בייטים של מילוי לפני כל פריט אם צריך כדי להשיג התאמה נכונה.
link_data ubyte[] נתונים שמשמשים בקבצים מקושרים באופן סטטי. הפורמט של הנתונים בקטע הזה לא מצוין במסמך הזה. הקטע הזה ריק בקבצים ללא קישור, והטמעות בסביבת זמן הריצה יכולות להשתמש בו כפי שהן רואות לנכון.

פורמט הקונטיינר

בגרסה 41 נוסף פורמט מאגר חדש לנתוני DEX, במטרה לחסוך מקום. פורמט הקונטיינר הזה מאפשר לשלב כמה קובצי DEX לוגיים בקובץ פיזי אחד. הפורמט החדש הוא בעיקר רק שרשור פשוט של קבצים בפורמט הקודם, עם כמה הבדלים:

  • הערך של file_size הוא הגודל של הקובץ הלוגי, ולא של הקובץ הפיזי. אפשר להשתמש בו כדי להריץ איטרציה על כל הקבצים הלוגיים בקונטיינר.
  • קובצי dex לוגיים יכולים להפנות לנתונים מאוחרים יותר בקונטיינר (אבל לא לנתונים קודמים). כך קבצי dex יכולים לשתף ביניהם נתונים, כמו מחרוזות.
  • כל הזזות האופרטור הן ביחס לקובץ הפיזי. אין שום הזזה ביחס לכותרת. כך אפשר לשתף קטעים עם סטיות בין קבצים לוגיים.
  • הכותרת מוסיפה שני שדות חדשים שמתארים את גבולות המאגר. זוהי בדיקת עקביות נוספת, והיא מאפשרת להעביר קוד לפורמט החדש בקלות רבה יותר.
  • התגים data_size ו-data_off לא בשימוש. הנתונים יכולים להיות מפוזרים במספר קבצים לוגיים, והם לא חייבים להיות רציפים.

הגדרות של שדות ביט, מחרוזות וקבועים

DEX_FILE_MAGIC

מוטמע ב-header_item

מערך/מחרוזת הקבוע DEX_FILE_MAGIC הוא רשימת הבייטים שצריכה להופיע בתחילת קובץ .dex כדי שהוא יזוהה ככזה. הערך מכיל בכוונה שורת חדשה ("\n" או 0x0a) ו-byte null ("\0" או 0x00) כדי לעזור בזיהוי של צורות מסוימות של פגיעה. הערך גם מכיל קידוד של מספר גרסת הפורמט בתור שלוש ספרות עשרוניות, שצפוי לעלות באופן מונוטוני לאורך זמן ככל שהפורמט יתפתח.

ubyte[8] DEX_FILE_MAGIC = { 0x64 0x65 0x78 0x0a 0x30 0x33 0x39 0x00 }
                        = "dex\n039\0"

הערה: התמיכה בגרסה 040 של הפורמט נוספה במהדורה 10.0 של Android, והרחיבה את קבוצת התווים המותרים ב-SimpleNames.

הערה: התמיכה בגרסה 039 של הפורמט נוספה במהדורה 9.0 של Android, שבה הוצגו שני בייטים חדשים, const-method-handle ו-const-method-type. (האפשרויות האלה מתוארות בטבלה סיכום של קבוצת קוד באקטי (bytecode)). ב-Android 10, גרסה 039 מרחיבה את פורמט קובץ ה-DEX כך שיכלול מידע API מוסתר שרלוונטי רק לקובצי DEX בנתיב של סיווג האתחול.

הערה: התמיכה בגרסה 038 של הפורמט נוספה במהדורה 8.0 של Android. בגרסה 038 נוספו קודי בייט חדשים (invoke-polymorphic ו-invoke-custom) ונתונים למטמון השיטות.

הערה: התמיכה בגרסה 037 של הפורמט נוספה במהדורת Android 7.0. לפני הגרסה 037, רוב הגרסאות של Android השתמשו בגרסה 035 של הפורמט. ההבדל היחיד בין הגרסאות 035 ו-037 הוא הוספת שיטות ברירת מחדל והתאמת invoke.

הערה: לפחות כמה גרסאות קודמות של הפורמט שימשו במהדורות תוכנה ציבוריות שזמינות באופן נרחב. לדוגמה, גרסה 009 שימשה למהדורות M3 של פלטפורמת Android (נובמבר-דצמבר 2007), וגרסה 013 שימשה למהדורות M5 של פלטפורמת Android (פברואר-מרץ 2008). יש כמה הבדלים משמעותיים בין הגרסאות הקודמות של הפורמט לבין הגרסה שמתוארת במסמך הזה.

ENDIAN_CONSTANT ו-REVERSE_ENDIAN_CONSTANT

מוטמע ב-header_item

הקבוע ENDIAN_CONSTANT משמש לציון endianness של הקובץ שבו הוא נמצא. אמנם הפורמט הסטנדרטי של .dex הוא little-endian, אבל בהטמעות מסוימות יכול להיות שיתבצע החלפת בייטים. אם במהלך הטמעה יתגלה כותרת שבה הערך של endian_tag הוא REVERSE_ENDIAN_CONSTANT במקום ENDIAN_CONSTANT, תהיה אפשרות לדעת שהקובץ עבר החלפה של ביטים מהפורמט הצפוי.

uint ENDIAN_CONSTANT = 0x12345678;
uint REVERSE_ENDIAN_CONSTANT = 0x78563412;

NO_INDEX

מוטמעים ב-class_def_item וב-debug_info_item

הקבוע NO_INDEX משמש לציון שהערך של המדד חסר.

הערה: הערך הזה לא מוגדר כ-0, כי בדרך כלל זהו אינדקס תקין.

הערך שנבחר ל-NO_INDEX יכול להיות מיוצג כבייט יחיד בקידוד uleb128p1.

uint NO_INDEX = 0xffffffff;    // == -1 if treated as a signed int

הגדרות של access_flags

מוטמע ב-class_def_item,‏ encoded_field,‏ encoded_method ו-InnerClass

שדות הביט של הדגלים האלה משמשים לציון הנגישות והמאפיינים הכוללים של כיתות ומשתני מחלקה.

שם ערך לכיתות (ולתווית הערה InnerClass) לשדות לשיטות
ACC_PUBLIC 0x1 public: גלוי בכל מקום public: גלוי בכל מקום public: גלוי בכל מקום
ACC_PRIVATE 0x2 * private: גלוי רק לכיתה המגדירה private: גלוי רק לכיתה המגדירה private: גלוי רק לכיתה המגדירה
ACC_PROTECTED 0x4 * protected: גלוי לחבילה ולתת-הסוגים protected: גלוי לחבילה ולתת-כיתות protected: גלוי לחבילה ולתת-כיתות
ACC_STATIC 0x8 * static: לא נוצר באמצעות הפניה חיצונית של this static: גלובלי לכיתה המגדירה static: לא מקבלת ארגומנט this
ACC_FINAL 0x10 final: לא ניתן ליצור צאצאים שלהם final: לא ניתן לשינוי אחרי היצירה final: לא ניתן לשנות
ACC_SYNCHRONIZED 0x20     synchronized: נעילת המפתח שמשויכת לקריאה לשיטה הזו נרכשת באופן אוטומטי.

הערה: אפשר להגדיר את הערך הזה רק כשגם הערך ACC_NATIVE מוגדר.

ACC_VOLATILE 0x40   volatile: כללי גישה מיוחדים שיעזרו לשמור על הבטיחות בשרשור  
ACC_BRIDGE 0x40     שיטת גשר, שנוספת באופן אוטומטי על ידי המהדר כגשר בטוח לסוגים
ACC_TRANSIENT 0x80   transient: לא יישמרו בסריאליזציה כברירת מחדל  
ACC_VARARGS 0x80     הארגומנט האחרון צריך להיחשב כארגומנט 'שאר' על ידי המהדר
ACC_NATIVE 0x100     native: מוטמע בקוד Native
ACC_INTERFACE 0x200 interface: מחלקה מופשטת שאפשר להטמיע אותה בכמה דרכים    
ACC_ABSTRACT 0x400 abstract: לא ניתן ליצור אובייקט ישירות   abstract: לא מיושם על ידי הכיתה הזו
ACC_STRICT 0x800     strictfp: כללים מחמירים לחשבון של נקודה צפה
ACC_SYNTHETIC 0x1000 לא מוגדרים ישירות בקוד המקור לא מוגדרים ישירות בקוד המקור לא מוגדרים ישירות בקוד המקור
ACC_ANNOTATION 0x2000 מוצהרת ככיתה של הערות    
ACC_ENUM 0x4000 מוצהרים כסוגים של ערכים ממוספרים מוצהר כערך ממוספר  
(לא בשימוש) 0x8000      
ACC_CONSTRUCTOR 0x10000     שיטת constructor (מפעילה של סוג או מופע)
ACC_DECLARED_
SYNCHRONIZED
0x20000     הצהרת על synchronized.

הערה: אין לכך השפעה על הביצוע (מלבד השתקפות הדגל הזה, כשלעצמו).

* מותר להפעיל את התכונה רק בהערות InnerClass, אסור להפעיל אותה ב-class_def_item.

קידוד UTF-8 שעבר שינוי

כדי לאפשר תמיכה קלה יותר בקוד מדור קודם, הפורמט .dex מקודד את נתוני המחרוזות שלו בצורה של UTF-8 שהותאמה לתקן בפועל, שנקראת מעכשיו MUTF-8. הטופס הזה זהה ל-UTF-8 רגיל, מלבד:

  • נעשה שימוש רק בקידוד של בייטים אחדים, שניים ושלושה.
  • נקודות קוד בטווח U+10000U+10ffff מקודדות כזוג סמלי עזר, שכל אחד מהם מיוצג כערך מקודד בן שלושה בייטים.
  • נקודת הקוד U+0000 מקודדת בפורמט של שני בייטים.
  • בית אפס רגיל (ערך 0) מציין את סוף המחרוזת, בהתאם למשמעות הרגילה בשפת C.

אפשר לסכם את שני הפריטים הראשונים שלמעלה כך: MUTF-8 הוא פורמט קידוד של UTF-16, במקום פורמט קידוד ישיר יותר של תווים ב-Unicode.

שני הפריטים האחרונים שלמעלה מאפשרים לכלול בו-זמנית את נקודת הקוד U+0000 במחרוזת וגם לבצע בה מניפולציות כמחרוזת מסוג C עם סיומת null.

עם זאת, הקידוד המיוחד של U+0000 אומר שבניגוד ל-UTF-8 רגיל, התוצאה של קריאה לפונקציית C הרגילה strcmp() על זוג מחרוזות MUTF-8 לא תמיד מציינת את התוצאה החתומה כראוי של השוואה בין מחרוזות לא שוות. כשחשוב לשמור על הסדר (ולא רק על השוויון), הדרך הפשוטה ביותר להשוות בין מחרוזות MUTF-8 היא לפענח אותן תו אחר תו ולהשוות בין הערכים שפורשו. (עם זאת, אפשר גם לבצע הטמעות חכמות יותר).

מידע נוסף על קידוד תווים זמין בתקן Unicode. למעשה, MUTF-8 קרוב יותר לקידוד CESU-8 (פחות ידוע יחסית) מאשר ל-UTF-8.

קידוד של encoded_value

מוטמע ב-annotation_element וב-encoded_array_item

encoded_value הוא קטע נתונים מקודד של נתונים (כמעט) שרירותיים שמאורגנים בהיררכיה. ההמרה אמורה להיות קומפקטית ופשוטה לניתוח.

שם פורמט תיאור
(value_arg << 5) | value_type ubyte בייט שמציין את הסוג של value שמיד אחריו, יחד עם ארגומנטים מפורטים אופציונליים בשלושת הביטים הבכירים. בהמשך מפורטות ההגדרות השונות של value. ברוב המקרים, value_arg מקודד את האורך של value העוקב אחריו מיידית ביחידות ביייט, כפי שמתואר ב-(size - 1), לדוגמה: הערך 0 מציין שהערך נדרש בתור בית אחד, והערך 7 מציין שהערך נדרש בתור שמונה בתים. עם זאת, יש יוצאים מן הכלל כפי שמפורט בהמשך.
ערך ubyte[] בייטים שמייצגים את הערך, באורך משתנה, ומתפרשים באופן שונה לבייטים שונים של value_type, אבל תמיד בפורמט little-endian. בהמשך מפורטות הגדרות הערכים השונות.

פורמטים של ערכים

שם הסוג value_type value_arg פורמט value פורמט תיאור
VALUE_BYTE 0x00 (ללא; חייב להיות 0) ubyte[1] ערך שלם חתום באורך ביייט אחד
VALUE_SHORT 0x02 size - 1‏ (0…1) ubyte[size] ערך שלם חתום באורך שני בתים, עם סימן מורחב
VALUE_CHAR 0x03 size - 1‏ (0…1) ubyte[size] ערך שלם ללא סימן באורך שני בייטים, עם הרחבה לאפס
VALUE_INT 0x04 size - 1‏ (0…3) ubyte[size] ערך שלם חתום באורך ארבעה בתים, עם סימן מורחב
VALUE_LONG 0x06 size - 1‏ (0…7) ubyte[size] ערך שלם חתום באורך שמונה בתים, עם סימן מורחב
VALUE_FLOAT 0x10 size - 1‏ (0…3) ubyte[size] תבנית ביטים של ארבעה בתים, עם הרחבה של אפס ימינה, ופרשנוּת כערך של נקודה צפה (floating point) של 32 ביט בתקן IEEE754
VALUE_DOUBLE 0x11 size - 1‏ (0…7) ubyte[size] תבנית ביטים של שמונה בייטים, עם הרחבה של אפס ימינה, ופרשנוּת כערך של נקודה צפה (floating point) של 64 ביט בתקן IEEE754
VALUE_METHOD_TYPE 0x15 size - 1‏ (0…3) ubyte[size] ערך שלם של ארבעה בתים ללא סימן (מורחב לאפס), שמתפרש כאינדקס לקטע proto_ids ומייצג ערך של סוג שיטת
VALUE_METHOD_HANDLE 0x16 size - 1‏ (0…3) ubyte[size] ערך שלם לא חתום (מורחב לאפס) באורך ארבעה בתים, שמתפרש כאינדקס לקטע method_handles ומייצג ערך של טיפולי שיטות
VALUE_STRING 0x17 size - 1‏ (0…3) ubyte[size] ערך שלם ללא סימן (מורחב לאפס) באורך ארבעה בתים, שמתפרש כאינדקס לקטע string_ids ומייצג ערך מחרוזת
VALUE_TYPE 0x18 size - 1‏ (0…3) ubyte[size] ערך שלם של ארבעה בתים ללא סימן (מורחב באפס), שמתפרש כאינדקס לקטע type_ids ומייצג ערך של סוג/כיתה רפלקטיבי
VALUE_FIELD 0x19 size - 1‏ (0…3) ubyte[size] ערך שלם של ארבעה בתים ללא סימן (מורחב באפס), שמתפרש כאינדקס לקטע field_ids ומייצג ערך שדה רפלקטיבי
VALUE_METHOD 0x1a size - 1‏ (0…3) ubyte[size] ערך שלם לא חתום (מורחב לאפס) באורך ארבעה בייטים, שמתפרש כאינדקס לקטע method_ids ומייצג ערך של שיטת רפלקציה
VALUE_ENUM 0x1b size - 1‏ (0…3) ubyte[size] ערך שלם של ארבעה בתים ללא סימן (מורחב לאפס), שמתורגם כאינדקס בקטע field_ids ומייצג את הערך של קבוע מסוג Enumeration
VALUE_ARRAY 0x1c (ללא; חייב להיות 0) encoded_array מערך ערכים, בפורמט שצוין בקטע 'פורמט encoded_array' בהמשך. הגודל של value הוא סמוי בקידוד.
VALUE_ANNOTATION 0x1d (ללא; חייב להיות 0) encoded_annotation הערה משנית, בפורמט שמפורט בקטע 'פורמט encoded_annotation' בהמשך. הגודל של value הוא סמוי בקידוד.
VALUE_NULL 0x1e (ללא; חייב להיות 0) (none) ערך העזר של null
VALUE_BOOLEAN 0x1f בוליאני (0…1) (none) ערך של ביט אחד: 0 עבור false ו-1 עבור true. הבייט מיוצג ב-value_arg.

פורמט encoded_array

שם פורמט תיאור
size uleb128 מספר הרכיבים במערך
ערכים encoded_value[size] סדרה של רצפי size encoded_value בייטים בפורמט שצוין בקטע הזה, שמקושרים בסדר.

הפורמט של encoded_annotation

שם פורמט תיאור
type_idx uleb128 סוג ההערה. זה חייב להיות טיפוס של כיתה (לא מערך או פרימיטיבי).
size uleb128 מספר המיפויים של שם-ערך בהערה הזו
רכיבים annotation_element[size] רכיבי ההערה, שמוצגים ישירות בשורה (לא בתור הרכיבים צריכים להיות ממוינים בסדר עולה לפי אינדקס string_id.

פורמט של annotation_element

שם פורמט תיאור
name_idx uleb128 שם הרכיב, שמיוצג כאינדקס בקטע string_ids. המחרוזת חייבת להיות תואמת לתחביר של MemberName, שמוגדר למעלה.
ערך encoded_value ערך רכיב

תחביר של מחרוזת

יש כמה סוגים של פריטים בקובץ .dex, שבסופו של דבר מפנים למחרוזת. ההגדרות הבאות בסגנון BNF מצביעות על התחביר הקביל למחרוזות האלה.

SimpleName

SimpleName הוא הבסיס לתחביר של שמות של דברים אחרים. הפורמט .dex מאפשר הרבה גמישות (יותר מרוב שפות המקור הנפוצות). בקצרה, שם פשוט מורכב מכל תו או ספרה אלפביתי ב-ASCII נמוך, כמה סמלים ספציפיים ב-ASCII נמוך ורוב נקודות הקוד שאינן ASCII, שאינן תווים של בקרה, רווח או תווים מיוחדים. החל מגרסה 040, הפורמט מאפשר גם להשתמש בתווי רווח (קטגוריה Zs ב-Unicode). שימו לב שקודי סמלי חלופי (בטווח U+d800U+dfff) לא נחשבים כתוויות שם תקינות, אבל תווים משלימים של Unicode כן תקינים (והם מיוצגים על ידי החלופה האחרונה של הכלל ל-SimpleNameChar), וצריך לייצג אותם בקובץ כזוגות של קודי סמלי חלופי בקידוד MUTF-8.

SimpleName
SimpleNameChar (SimpleNameChar)*
SimpleNameChar
'A''Z'
| 'a''z'
| '0''9'
| ' ' מגרסה 040 של DEX והלאה
| '$'
| '-'
| '_'
| U+00a0 מגרסה 040 של DEX והלאה
| U+00a1U+1fff
| U+2000U+200a מגרסה 040 של DEX והלאה
| U+2010U+2027
| U+202f מגרסה 040 של DEX והלאה
| U+2030U+d7ff
| U+e000U+ffef
| U+10000U+10ffff

MemberName

משמש את field_id_item ואת method_id_item

MemberName הוא השם של חבר מחלקה, כאשר חברים הם שדות, שיטות ומחלקות פנימיות.

MemberName
SimpleName
| '<' SimpleName '>'

FullClassName

FullClassName הוא שם כיתה מלא, כולל מפריד חבילה אופציונלי ואחריו שם נדרש.

FullClassName
OptionalPackagePrefix SimpleName
OptionalPackagePrefix
(SimpleName '/')*

TypeDescriptor

בשימוש על ידי type_id_item

TypeDescriptor הוא ייצוג של כל סוג, כולל פרימיטיבים, מחלקות, מערכים ו-void. בהמשך מוסבר מה המשמעות של הגרסאות השונות.

TypeDescriptor
'V'
| FieldTypeDescriptor
FieldTypeDescriptor
NonArrayFieldTypeDescriptor
| ('[' * 1…255) NonArrayFieldTypeDescriptor
NonArrayFieldTypeDescriptor
'Z'
| 'B'
| 'S'
| 'C'
| 'I'
| 'J'
| 'F'
| 'D'
| 'L' FullClassName ';'

ShortyDescriptor

בשימוש על ידי proto_id_item

ShortyDescriptor הוא ייצוג בפורמט קצר של אב טיפוס של שיטה, כולל סוגי ההחזרה והפרמטרים, מלבד העובדה שאין הבחנה בין סוגי הפניות שונים (כיתה או מערך). במקום זאת, כל סוגי ההפניות מיוצגים על ידי תו 'L' יחיד.

ShortyDescriptor
ShortyReturnType (ShortyFieldType)*
ShortyReturnType
'V'
| ShortyFieldType
ShortyFieldType
'Z'
| 'B'
| 'S'
| 'C'
| 'I'
| 'J'
| 'F'
| 'D'
| 'L'

סמנטיקה של TypeDescriptor

זהו המשמעות של כל אחת מהוריאציות של TypeDescriptor.

תחביר משמעות
V void; תקף רק לסוגים של ערכים שמוחזרים
Z boolean
B byte
S short
C char
I int
J long
F float
D double
Lfully/qualified/Name; הכיתה fully.qualified.Name
[descriptor מערך של descriptor, שאפשר להשתמש בו באופן רפלוקטיבי למערכים של מערכים, אבל לא ניתן לכלול יותר מ-255 מאפיינים.

פריטים ומבנים קשורים

בקטע הזה מפורטות הגדרות של כל הפריטים ברמה העליונה שעשויים להופיע בקובץ .dex.

header_item

מופיע בקטע הכותרת

התאמה: 4 בייטים

שם פורמט תיאור
magic ubyte[8] = DEX_FILE_MAGIC ערך קסום. פרטים נוספים מופיעים בקטע DEX_FILE_MAGIC למעלה.
סכום כולל uint סיכום הביקורת של adler32 של שאר הקובץ (כל מה שחוץ מ-magic והשדה הזה). משמש לזיהוי פגיעה בקובץ
חתימה ubyte[20] חתימה (hash) מסוג SHA-1 של שאר הקובץ (כל מה שחוץ מ-magic,‏ checksum והשדה הזה). החתימה משמשת לזיהוי ייחודי של קבצים.
file_size uint

הגודל של הקובץ כולו (כולל הכותרת), בבייטים (גרסה 40 ואילך)

המרחק בבייט מתחילת הכותרת הזו לכותרת הבאה או לסוף הקובץ כולו (המארז). (גרסה 41 ואילך)

header_size uint

גודל הכותרת (כל הקטע הזה), בבייטים. כך אפשר לאפשר לפחות תאימות מוגבלת לאחור או קדימה בלי לפסול את הפורמט.

חייב להיות באורך 0x70 (112) בייטים (גרסה 40 ואילך)

חייב להיות 0x78 (120) בייטים (גרסה 41 ואילך)

endian_tag uint = ENDIAN_CONSTANT תג endianness. פרטים נוספים מופיעים למעלה בקטע 'ENDIAN_CONSTANT ו-REVERSE_ENDIAN_CONSTANT'.
link_size uint הגודל של קטע הקישור, או 0 אם הקובץ לא מקושר באופן סטטי
link_off uint הזזה מתחילת הקובץ לקטע הקישור, או 0 אם link_size == 0. אם הערך של ההיסט הוא לא אפס, הוא צריך להצביע להיסט בתוך הקטע link_data. הפורמט של הנתונים שמוצגים לא צוין במסמך הזה. שדה הכותרת הזה (והקודם) נשארים כוונטיות לשימוש בהטמעות בסביבת זמן הריצה.
map_off uint אופסט מתחילת הקובץ לפריט המפה. ההיסט, שחייב להיות שונה מאפס, צריך להצביע על היסט בקטע data, והנתונים צריכים להיות בפורמט שצוין ב-map_list בהמשך.
string_ids_size uint מספר המחרוזות ברשימה של מזהי המחרוזות
string_ids_off uint הזזה מתחילת הקובץ לרשימה של מזהים של מחרוזות, או 0 אם string_ids_size == 0 (אמנם מקרה קיצוני מוזר). אם הערך של ההיסט שונה מאפס, הוא צריך להיות בתחילת הקטע string_ids.
type_ids_size uint מספר הפריטים ברשימת מזהי הסוגים, לכל היותר 65,535
type_ids_off uint אופסט מתחילת הקובץ לרשימה של מזהי הסוגים, או 0 אם type_ids_size == 0 (אמנם מקרה קיצוני מוזר). אם הערך של ההיסט שונה מאפס, הוא צריך להיות בתחילת הקטע type_ids.
proto_ids_size uint מספר הפריטים ברשימה של מזהי האב טיפוס, לכל היותר 65,535
proto_ids_off uint אופסט מתחילת הקובץ לרשימה של מזהי האב טיפוס, או 0 אם proto_ids_size == 0 (אמנם מקרה קיצוני מוזר). אם הערך של ההיסט שונה מאפס, הוא צריך להיות בתחילת הקטע proto_ids.
field_ids_size uint מספר הפריטים ברשימת מזהי השדות
field_ids_off uint הזזה מתחילת הקובץ לרשימת מזהי השדות, או 0 אם field_ids_size == 0. אם הערך של ההיסט שונה מאפס, הוא צריך להיות בתחילת הקטע field_ids.
method_ids_size uint מספר הרכיבים ברשימת מזהי השיטות
method_ids_off uint הזזה מתחילת הקובץ לרשימה של מזהי השיטות, או 0 אם method_ids_size == 0. אם הערך של ההיסט שונה מאפס, הוא צריך להיות בתחילת הקטע method_ids.
class_defs_size uint מספר הפריטים ברשימת הגדרות הכיתה
class_defs_off uint OFFSET מתחילת הקובץ לרשימה של הגדרות הכיתות, או 0 אם class_defs_size == 0 (אמנם מקרה קיצוני ומוזר). אם הערך של ההיסט שונה מאפס, הוא צריך להיות בתחילת הקטע class_defs.
data_size uint

הגודל של הקטע data בבייטים. חייב להיות כפולה זוגית של sizeof(uint). (גרסה 40 ואילך)

לא בשימוש (גרסה 41 ואילך)

data_off uint

הזזה מתחילת הקובץ לתחילת הקטע data (גרסה 40 ואילך)

לא בשימוש (גרסה 41 ואילך)

container_size uint

השדה הזה לא קיים. אפשר להניח שהוא שווה ל-file_size. (גרסה 40 ואילך)

הגודל של הקובץ כולו (כולל כותרות dex אחרות והנתונים שלהן). (גרסה 41 ואילך)

header_offset uint

השדה הזה לא קיים. אפשר להניח שהוא שווה ל-0. (גרסה 40 ואילך)

היסט מתחילת הקובץ לתחילת הכותרת הזו. (גרסה 41 ואילך)

map_list

מופיע בקטע 'נתונים'

הפניה מ-header_item

התאמה: 4 בייטים

זוהי רשימה של כל התוכן בקובץ, לפי סדר. הוא מכיל קצת יתירות ביחס ל-header_item, אבל הוא מיועד להיות טופס קל לשימוש כדי לבצע איטרציה על קובץ שלם. סוג מסוים חייב להופיע במפה רק פעם אחת, אבל אין הגבלה על סוגי ההזמנות שיכולים להופיע, מלבד ההגבלות שמשתמעות משאר הפורמט (למשל, הקטע header חייב להופיע קודם, ואחריו הקטע string_ids וכו'). בנוסף, רשומות המפה צריכות להיות מסודרות לפי הזזה ראשונית ואסור שהן יחפפו.

שם פורמט תיאור
size uint גודל הרשימה, בכניסות
רשימה map_item[size] הרכיבים של הרשימה

הפורמט של map_item

שם פורמט תיאור
סוג ushort סוג הפריטים. אפשר לעיין בטבלה שבהמשך.
unused ushort (לא בשימוש)
size uint מספר הפריטים שצריך למצוא בהיסט שצוין
לקזז uint הזזה מתחילת הקובץ לפריטים הרלוונטיים

הקלדה של קודים

סוג הפריט קבוע ערך גודל הפריט בבייטים
header_item TYPE_HEADER_ITEM 0x0000 0x70
string_id_item TYPE_STRING_ID_ITEM 0x0001 0x04
type_id_item TYPE_TYPE_ID_ITEM 0x0002 0x04
proto_id_item TYPE_PROTO_ID_ITEM 0x0003 0x0c
field_id_item TYPE_FIELD_ID_ITEM 0x0004 0x08
method_id_item TYPE_METHOD_ID_ITEM 0x0005 0x08
class_def_item TYPE_CLASS_DEF_ITEM 0x0006 0x20
call_site_id_item TYPE_CALL_SITE_ID_ITEM 0x0007 0x04
method_handle_item TYPE_METHOD_HANDLE_ITEM 0x0008 0x08
map_list TYPE_MAP_LIST 0x1000 4 + (item.size * 12)
type_list TYPE_TYPE_LIST 0x1001 4 + (item.size * 2)
annotation_set_ref_list TYPE_ANNOTATION_SET_REF_LIST 0x1002 4 + (item.size * 4)
annotation_set_item TYPE_ANNOTATION_SET_ITEM 0x1003 4 + (item.size * 4)
class_data_item TYPE_CLASS_DATA_ITEM 0x2000 משתמע; חייב לנתח
code_item TYPE_CODE_ITEM 0x2001 משתמע; חייב לנתח
string_data_item TYPE_STRING_DATA_ITEM 0x2002 משתמע; חייב לנתח
debug_info_item TYPE_DEBUG_INFO_ITEM 0x2003 משתמע; חייב לנתח
annotation_item TYPE_ANNOTATION_ITEM 0x2004 משתמע; חייב לנתח
encoded_array_item TYPE_ENCODED_ARRAY_ITEM 0x2005 משתמע; חייב לנתח
annotations_directory_item TYPE_ANNOTATIONS_DIRECTORY_ITEM 0x2006 משתמע; חייב לנתח
hiddenapi_class_data_item TYPE_HIDDENAPI_CLASS_DATA_ITEM 0xF000 משתמע; חייב לנתח

string_id_item

מופיע בקטע string_ids

התאמה: 4 בייטים

שם פורמט תיאור
string_data_off uint הזזה מתחילת הקובץ לנתוני המחרוזת של הפריט הזה. ההיסט צריך להיות למיקום בקטע data, והנתונים צריכים להיות בפורמט שמפורט ב-string_data_item בהמשך. אין דרישה ליישור של ההיסט.

string_data_item

מופיע בקטע 'נתונים'

התאמה: ללא (יישור לפי בייטים)

שם פורמט תיאור
utf16_size uleb128 הגודל של המחרוזת הזו, ביחידות קוד UTF-16 (הגודל הזה נקרא 'אורך המחרוזת' במערכות רבות). כלומר, זהו האורך של המחרוזת לאחר פענוח. (אורך ההצפנה נגזר מהמיקום של הבית 0).
נתונים ubyte[] סדרה של יחידות קוד MUTF-8 (שנקראות גם אוקטטים או בייטים) ואחריה בייט עם הערך 0. למידע נוסף על פורמט הנתונים, ראו 'קידוד MUTF-8 (UTF-8 שונה)' למעלה.

הערה: מותר לכלול במחרוזת (את הצורה הקודדת של) יחידות קוד חלופיות של UTF-16 (כלומר, U+d800U+dfff), בנפרד או בסדר שונה מהקידוד הרגיל של Unicode ל-UTF-16. אם צריך, המערכת תדחה קידודים לא חוקיים כאלה ברמות גבוהות יותר של שימוש במחרוזות.

type_id_item

מופיע בקטע type_ids

התאמה: 4 בייטים

שם פורמט תיאור
descriptor_idx uint מאתרים את מחרוזת המתאר של הסוג הזה ברשימה string_ids. המחרוזת חייבת להתאים לתחביר של TypeDescriptor, שמוגדר למעלה.

proto_id_item

מופיע בקטע proto_ids

התאמה: 4 בייטים

שם פורמט תיאור
shorty_idx uint מאתרים את המחרוזת של התיאור המקוצר של אב הטיפוס ברשימה string_ids. המחרוזת חייבת להתאים לתחביר של ShortyDescriptor, שהוגדר למעלה, ולהתאים לסוג ההחזרה ולפרמטרים של הפריט הזה.
return_type_idx uint מאתרים את סוג ההחזרה של אב הטיפוס הזה ברשימה type_ids
parameters_off uint הזזה מתחילת הקובץ אל רשימת סוגי הפרמטרים של האב-טיפוס, או 0 אם אין לאב-טיפוס פרמטרים. אם הערך של ההיסט הוא לא אפס, הוא צריך להופיע בקטע data, והנתונים שם צריכים להיות בפורמט שמוגדר על ידי "type_list" בהמשך. בנוסף, לא אמורה להיות ברשימה הפניה לסוג void.

field_id_item

מופיע בקטע field_ids

התאמה: 4 בייטים

שם פורמט תיאור
class_idx ushort אינדקס ברשימה type_ids של מי שהגדיר את השדה הזה. זה חייב להיות טיפוס של כיתה, ולא מערך או טיפוס פרימיטיבי.
type_idx ushort חיפוש ברשימה type_ids לפי סוג השדה
name_idx uint מחפשים את השם של השדה הזה ברשימה string_ids. המחרוזת חייבת להיות תואמת לתחביר של MemberName, שמוגדר למעלה.

method_id_item

מופיע בקטע method_ids

התאמה: 4 בייטים

שם פורמט תיאור
class_idx ushort האינדקס ברשימה type_ids של המגדיר של השיטה הזו. זה חייב להיות טיפוס של מחלקה או מערך, ולא טיפוס פרימיטיבי.
proto_idx ushort מאתרים את האב טיפוס של השיטה הזו ברשימה proto_ids
name_idx uint מחפשים את השם של השיטה הזו ברשימה string_ids. המחרוזת חייבת להיות תואמת לתחביר של MemberName, שמוגדר למעלה.

class_def_item

מופיע בקטע class_defs

התאמה: 4 בייטים

שם פורמט תיאור
class_idx uint להוסיף את הכיתה הזו לאינדקס של רשימת type_ids. זה חייב להיות טיפוס של כיתה, ולא מערך או טיפוס פרימיטיבי.
access_flags uint דגלים של גישה לכיתה (public,‏ final וכו'). פרטים נוספים זמינים בקטע access_flags הגדרות.
superclass_idx uint אינדקס ברשימה type_ids של הסוג ההורה, או הערך הקבוע NO_INDEX אם אין לסוג הזה סוג הורה (כלומר, הוא סוג ברמה הבסיסית, כמו Object). אם הוא קיים, הוא חייב להיות סוג של סוג ולא מערך או סוג פרימיטיבי.
interfaces_off uint הזזה מתחילת הקובץ לרשימה של הממשקים, או 0 אם אין כאלה. ההיסט הזה צריך להיות בקטע data, והנתונים שם צריכים להיות בפורמט שמפורט ב-type_list בהמשך. כל אחד מהאלמנטים ברשימה חייב להיות מסוג class (לא מערך או סוג פרימיטיבי), ואסור שיהיו עותקים כפולים.
source_file_idx uint מאתרים ברשימה string_ids את השם של הקובץ שמכיל את המקור המקורי (לפחות רוב) של הכיתה הזו, או את הערך המיוחד NO_INDEX כדי לייצג את היעדר המידע הזה. ה-debug_info_item של כל שיטה נתונה יכול לשנות את קובץ המקור הזה, אבל ההנחה היא שרוב הכיתות יגיעו מקובץ מקור אחד בלבד.
annotations_off uint הזזה מתחילת הקובץ למבנה ההערות של הכיתה הזו, או 0 אם אין הערות בכיתה הזו. אם הערך של ההיסט הוא לא אפס, הוא צריך להופיע בקטע data, והנתונים שם צריכים להיות בפורמט שמוגדר ב-annotations_directory_item בהמשך, כאשר כל הפריטים מתייחסים לכיתה הזו בתור המגדיר.
class_data_off uint הזזה מתחילת הקובץ לנתוני הכיתה המשויכים לפריט הזה, או 0 אם אין נתוני כיתה לכיתה הזו. (הדבר יכול לקרות, למשל, אם הכיתה היא ממשק סמן). אם הערך של ההיסט הוא לא אפס, הוא צריך להופיע בקטע data, והנתונים שם צריכים להיות בפורמט שמפורט ב-class_data_item בהמשך, כאשר כל הפריטים מתייחסים לכיתה הזו בתור המגדיר.
static_values_off uint הזזה מתחילת הקובץ לרשימה של הערכים הראשוניים לשדות static, או 0 אם אין כאלה (וכל שדות static צריכים להיות מוגדרים ב-0 או ב-null). ההזזה הזו צריכה להיות בקטע data, והנתונים שם צריכים להיות בפורמט שצוין ב-encoded_array_item בהמשך. הגודל של המערך לא יכול להיות גדול ממספר השדות מסוג static שהוגדר בכיתה הזו, והרכיבים תואמים לשדות static באותו הסדר שבו הם הוגדרו ב-field_list התואם. הסוג של כל רכיב במערך חייב להתאים לסוג המוצהר של השדה התואם. אם יש ברשימה פחות רכיבים ממספר השדות של static, השדות הנותרים יופעלו עם 0 או null שמתאימים לסוג.

call_site_id_item

מופיע בקטע call_site_ids

התאמה: 4 בייטים

שם פורמט תיאור
call_site_off uint הזזה מתחילת הקובץ כדי לקרוא להגדרת האתר. ההיסט צריך להיות בקטע הנתונים, והנתונים שם צריכים להיות בפורמט שמפורט בהמשך בקטע 'call_site_item'.

call_site_item

מופיע בקטע 'נתונים'

התאמה: ללא (יישור לפי בייטים)

ה-call_site_item הוא encoded_array_item שהאלמנטים שלו תואמים לארגומנטים שסופקו לשיטת הקישור של Bootstrap. שלושת הארגומנטים הראשונים הם:

  1. מאגר שיטות שמייצג את שיטת הקישור של האתחול (VALUE_METHOD_HANDLE).
  2. שם של שיטה שהמקשר של Bootstrap צריך לפתור (VALUE_STRING).
  3. סוג method שתואם לסוג של שם method שצריך לפתור (VALUE_METHOD_TYPE).

כל ארגומנטים נוספים הם ערכים קבועים שמועברים לשיטת הקישור של Bootstrap. הארגומנטים האלה מועברים לפי הסדר וללא המרות של סוגים.

לסוג ההחזרה של ה-method handle שמייצג את שיטת הקישור של האתחול צריך להיות java.lang.invoke.CallSite. שלושת סוגי הפרמטרים הראשונים הם:

  1. java.lang.invoke.Lookup
  2. java.lang.String
  3. java.lang.invoke.MethodType

סוגי הפרמטרים של ארגומנטים נוספים נקבעים על סמך הערכים הקבועים שלהם.

method_handle_item

מופיע בקטע method_handles

התאמה: 4 בייטים

שם פורמט תיאור
method_handle_type ushort הסוג של ה-method handle. אפשר לעיין בטבלה שבהמשך.
unused ushort (לא בשימוש)
field_or_method_id ushort מזהה שדה או שיטת, בהתאם לסוג של רכיב הטיפול בשיטה (method handle) שהוא רכיב גישה או מפעיל שיטות
unused ushort (לא בשימוש)

קודים של סוגי הידית של שיטות

קבוע ערך תיאור
METHOD_HANDLE_TYPE_STATIC_PUT 0x00 Method handle הוא מגדיר שדה סטטי (רכיב גישה)
METHOD_HANDLE_TYPE_STATIC_GET 0x01 Method handle הוא פונקציית אחזור סטטית של שדה (accessor)
METHOD_HANDLE_TYPE_INSTANCE_PUT 0x02 ה-method handle הוא מגדיר שדה של מופע (רכיב גישה)
METHOD_HANDLE_TYPE_INSTANCE_GET 0x03 Method handle הוא פונקציית אחזור (accessor) של שדה מופע
METHOD_HANDLE_TYPE_INVOKE_STATIC 0x04 Method handle הוא מפעיל סטטי של שיטות
METHOD_HANDLE_TYPE_INVOKE_INSTANCE 0x05 Method handle הוא מבצע של קריאה לשיטת מופע
METHOD_HANDLE_TYPE_INVOKE_CONSTRUCTOR 0x06 Method handle הוא מבצע קריאה לשיטת קונסטרוקטור
METHOD_HANDLE_TYPE_INVOKE_DIRECT 0x07 Method handle הוא מפעיל שיטות ישיר
METHOD_HANDLE_TYPE_INVOKE_INTERFACE 0x08 Method handle הוא מבצע קריאה לשיטת ממשק

class_data_item

הפניה מ-class_def_item

מופיע בקטע 'נתונים'

התאמה: ללא (יישור לפי בייטים)

שם פורמט תיאור
static_fields_size uleb128 מספר השדות הסטטיים שמוגדרים בפריט הזה
instance_fields_size uleb128 מספר שדות המכונה שמוגדרים בפריט הזה
direct_methods_size uleb128 מספר השיטות הישירות שהוגדרו בפריט הזה
virtual_methods_size uleb128 מספר השיטות הווירטואליות שמוגדרות בפריט הזה
static_fields encoded_field[static_fields_size] השדות הסטטיים שהוגדרו, שמיוצגים כרצף של רכיבים מקודדים. צריך למיין את השדות לפי field_idx בסדר עולה.
instance_fields encoded_field[instance_fields_size] שדות המכונה שהוגדרו, שמיוצגים כרצף של רכיבים מקודדים. צריך למיין את השדות לפי field_idx בסדר עולה.
direct_methods encoded_method[direct_methods_size] השיטות הישירות שהוגדרו (כל אחת מ-static,‏ private או ה-constructor), שמיוצגות כרצף של רכיבים מקודדים. צריך למיין את השיטות לפי method_idx בסדר עולה.
virtual_methods encoded_method[virtual_methods_size] השיטות הווירטואליות שהוגדרו (לא static,‏ private או ה-constructor), שמיוצגות כרצף של אלמנטים מקודדים. הרשימה הזו לא צריכה לכלול שיטות שעברו בירושה, אלא אם הן שונו על ידי הכיתה שהפריט הזה מייצג. צריך למיין את השיטות לפי method_idx בסדר עולה. method_idx של שיטת וירטואלית לא יכול להיות זהה לשיטה ישירה כלשהי.

הערה: כל המופעים של field_id ו-method_id של הרכיבים חייבים להפנות לאותה כיתה מגדירה.

הפורמט של encoded_field

שם פורמט תיאור
field_idx_diff uleb128 מאתרים ברשימה field_ids את הזהות של השדה הזה (כולל השם והתיאורים), שמיוצגת כהפרש מהאינדקס של הרכיב הקודם ברשימה. האינדקס של הרכיב הראשון ברשימה מיוצג ישירות.
access_flags uleb128 דגלי גישה לשדה (public,‏ final וכו'). פרטים נוספים זמינים בקטע access_flags הגדרות.

הפורמט של encoded_method

שם פורמט תיאור
method_idx_diff uleb128 האינדקס ברשימה method_ids של הזהות של השיטה הזו (כולל השם והתיאורים), שמיוצג כהפרש מהאינדקס של הרכיב הקודם ברשימה. האינדקס של הרכיב הראשון ברשימה מיוצג ישירות.
access_flags uleb128 דגלי גישה לשיטה (public, final וכו'). פרטים נוספים זמינים בקטע access_flags הגדרות.
code_off uleb128 אופסט מתחילת הקובץ למבנה הקוד של השיטה הזו, או 0 אם השיטה הזו היא abstract או native. ההיסט צריך להיות למיקום בקטע data. הפורמט של הנתונים מצוין ב-code_item בהמשך.

type_list

הפניה מ-class_def_item ומ-proto_id_item

מופיע בקטע 'נתונים'

התאמה: 4 בייטים

שם פורמט תיאור
size uint גודל הרשימה, בכניסות
רשימה type_item[size] הרכיבים של הרשימה

הפורמט של type_item

שם פורמט תיאור
type_idx ushort אינדקס ברשימה type_ids

code_item

הפניה מ-encoded_method

מופיע בקטע 'נתונים'

התאמה: 4 בייטים

שם פורמט תיאור
registers_size ushort מספר הרשומות שבהן הקוד הזה משתמש
ins_size ushort מספר המילים של הארגומנטים הנכנסים לשיטה שהקוד הזה מיועד לה
outs_size ushort מספר המילים של שטח הארגומנטים היוצאים שנדרש לקוד הזה להפעלת השיטה
tries_size ushort מספר ה-try_item של המופע הזה. אם הערך שונה מאפס, הערכים האלה מופיעים כמערך tries מיד אחרי הערך insns במופע הזה.
debug_info_off uint הזזה מתחילת הקובץ לרצף של פרטי ניפוי הבאגים (מספרי שורות + פרטי המשתנים המקומיים) של הקוד הזה, או 0 אם פשוט אין מידע. אם הערך של ההיסט שונה מאפס, הוא צריך להצביע למיקום בקטע data. הפורמט של הנתונים מצוין ב-debug_info_item בהמשך.
insns_size uint הגודל של רשימת ההוראות, ביחידות קוד של 16 ביט
insns ushort[insns_size] מערך הבייטקוד בפועל. הפורמט של הקוד במערך insns מצוין במסמך הנלווה Dalvik bytecode. חשוב לשים לב שלמרות שהמבנה מוגדר כמערך של ushort, יש מבנים פנימיים מסוימים שמעדיפים התאמה של ארבעה בייט. בנוסף, אם הקובץ הזה הוא קובץ עם החלפת endian, ההחלפה מתבצעת רק במופעים נפרדים של ushort ולא במבנים הפנימיים הגדולים יותר.
padding ushort (אופציונלי) = 0 שני בייטים של מילוי כדי שהשדה tries יתאים לארבעה בייטים. הרכיב הזה קיים רק אם tries_size שונה מאפס ו-insns_size הוא מספר אי-זוגי.
ניסיונות try_item[tries_size] (אופציונלי) מערך שמציין איפה בקוד מתרחשות חריגות ואיך מטפלים בהן. הרכיבים של המערך לא יכולים להיות חופפים בטווח, והם צריכים להיות מסודרים מהכתובת הנמוכה לכתובת הגבוהה. האלמנט הזה נמצא רק אם הערך של tries_size שונה מאפס.
רכיבי handler encoded_catch_handler_list (אופציונלי) בייטים שמייצגים רשימה של רשימות של סוגי catch וכתובות טיפול משויכות. לכל try_item יש סטייה של בייטים במבנה הזה. האלמנט הזה נמצא רק אם הערך של tries_size שונה מאפס.

הפורמט של try_item

שם פורמט תיאור
start_addr uint כתובת ההתחלה של בלוק הקוד שמתואר ברשומה הזו. הכתובת היא ספירה של יחידות קוד של 16 ביט עד לתחילת ההוראה הראשונה המכוסה.
insn_count ushort מספר יחידות הקוד של 16 ביט שמפורטות ברשומה הזו. יחידת הקוד האחרונה שכלולה בהסכם היא start_addr + insn_count - 1.
handler_off ushort הזזה בבייטים מתחילת ה-encoded_catch_hander_list המשויך אל ה-encoded_catch_handler של הרשומה הזו. זה חייב להיות היסט לתחילת encoded_catch_handler.

הפורמט של encoded_catch_handler_list

שם פורמט תיאור
size uleb128 הגודל של הרשימה הזו, במספר רשומות
רשימה encoded_catch_handler[handlers_size] רשימת רשימות הטיפולנים בפועל, שמיוצגת ישירות (לא כאופסים) ומקונצנטרנת ברצף

הפורמט של encoded_catch_handler

שם פורמט תיאור
size sleb128 מספר סוגי ה-catch ברשימה הזו. אם הערך לא חיובי, הוא הערך השלילי של מספר סוגי ה-catch, ואחריהם מופיע טיפול catch-all. לדוגמה: size של 0 פירושו שיש כלל לכולם, אבל אין קטגוריות ספציפיות לאירועים. size של 2 פירושו שיש שני טיפים של catch שצוינו במפורש, ואין catch-all. ו-size של -1 פירושו שיש כלל מסנן אחד ידני וכלל מסנן כללי.
רכיבי handler encoded_type_addr_pair[abs(size)] מקור נתונים של abs(size) פריטים מקודדים, אחד לכל סוג שנלכד, בסדר שבו צריך לבדוק את הסוגים.
catch_all_addr uleb128 (אופציונלי) כתובת ה-bytecode של הטיפול בכל הכתובות. האלמנט הזה מופיע רק אם הערך של size הוא שלילי.

הפורמט של encoded_type_addr_pair

שם פורמט תיאור
type_idx uleb128 חיפוש ברשימה type_ids לפי סוג החריג שרוצים לתפוס
addr uleb128 כתובת ה-bytecode של בורר החריגות המשויך

debug_info_item

הפניה מ-code_item

מופיע בקטע 'נתונים'

התאמה: ללא (יישור לפי בייטים)

כל debug_info_item מגדיר מכונת מצב בקידוד בייט בהשראת DWARF3, שבמהלך הפענוח שלה היא משדרת את טבלת המיקומים ואת פרטי המשתנה המקומי (אם רלוונטי) של code_item. הרצף מתחיל בכותרת באורך משתנה (האורך שלה תלוי במספר הפרמטרים של השיטה), ואחריה מופיעים הבייטקודים של מכונת המצבים, והוא מסתיים בבייט DBG_END_SEQUENCE.

מכונת המצב מורכבת מחמישה מרשם. הרישום address מייצג את ההיסט של ההוראה ב-insns_item המשויך ביחידות קוד של 16 ביט. המרשם address מתחיל ב-0 בתחילת כל רצף debug_info, וצריך רק לגדול באופן מונוטונית. המרשם line מייצג את מספר שורת המקור שצריך לשייך לרשומה הבאה בטבלת המיקומים שמופעלת על ידי מכונת המצבים. הוא מופעל בכותרת הרצף, ויכול להשתנות בכיוון חיובי או שלילי, אבל הוא אף פעם לא יכול להיות קטן מ-1. המרשם source_file מייצג את קובץ המקור שאליו מתייחסות הרשומות של מספרי השורות. הוא מופעל לערך של source_file_idx ב-class_def_item. שני המשתנים האחרים, prologue_end ו-epilogue_begin, הם דגלים בוליאנים (שמוגדרים ל-false) שמציינים אם המיקום הבא שיופץ צריך להיחשב כמבוא או כסיומת של method. מכונת המצבים צריכה גם לעקוב אחרי השם והסוג של המשתנה המקומי האחרון שפעיל בכל מרשם של קוד DBG_RESTART_LOCAL.

הכותרת נראית כך:

שם פורמט תיאור
line_start uleb128 הערך הראשוני של הרישום line של מכונת המצב. לא מייצג רשומה בפועל של עמדות.
parameters_size uleb128 מספר שמות הפרמטרים שמקודדים. צריך להיות אחד לכל פרמטר של שיטת, לא כולל this של שיטת מופע, אם יש כזה.
parameter_names uleb128p1[parameters_size] אינדקס המחרוזת של שם הפרמטר של השיטה. ערך מקודד של NO_INDEX מציין שאין שם זמין לפרמטר המשויך. התיאור והחתימה של הסוג משתמעים מהתיאור והחתימה של השיטה.

הערכים של קוד הבייטים הם:

שם ערך פורמט ארגומנטים תיאור
DBG_END_SEQUENCE 0x00 (none) סיום רצף של מידע על תוצאות ניפוי באגים של code_item
DBG_ADVANCE_PC 0x01 uleb128 addr_diff addr_diff: הסכום להוספה למרשם הכתובות מקדמים את מרשם הכתובות בלי להפיק רשומה של מיקומים
DBG_ADVANCE_LINE 0x02 sleb128 line_diff line_diff: הסכום שרוצים לשנות ברשומת הקו מקדמת את מרשם השורות בלי להפיק רשומה של מיקומים
DBG_START_LOCAL 0x03 uleb128 register_num
uleb128p1 name_idx
uleb128p1 type_idx
register_num: מרשם שיכיל את המשתנה המקומי
name_idx: אינדקס המחרוזת של השם
type_idx: אינדקס הסוג של הסוג
יוצרת משתנה מקומי בכתובת הנוכחית. הערך של name_idx או type_idx יכול להיות NO_INDEX כדי לציין שהערך לא ידוע.
DBG_START_LOCAL_EXTENDED 0x04 uleb128 register_num
uleb128p1 name_idx
uleb128p1 type_idx
uleb128p1 sig_idx
register_num: מרשם שיכיל מקומי
name_idx: אינדקס מחרוזת של השם
type_idx: אינדקס סוג של הסוג
sig_idx: אינדקס מחרוזת של חתימה של סוג
מגדיר משתנה מקומי עם חתימה של טיפוס בכתובת הנוכחית. כל אחד מהערכים name_idx,‏ type_idx או sig_idx יכול להיות NO_INDEX כדי לציין שהערך לא ידוע. (עם זאת, אם sig_idx הוא -1, אפשר לייצג את אותם נתונים בצורה יעילה יותר באמצעות קוד הפקודה DBG_START_LOCAL).

הערה: בהמשך, בקטע dalvik.annotation.Signature, מוסבר על האזהרות בנוגע לטיפול בחתימות.

DBG_END_LOCAL 0x05 uleb128 register_num register_num: רישום שהכיל local סימון משתנה מקומי פעיל כמשתנה מחוץ להיקף בכתובת הנוכחית
DBG_RESTART_LOCAL 0x06 uleb128 register_num register_num: רישום להפעלה מחדש מגדיר מחדש משתנה מקומי בכתובת הנוכחית. השם והסוג זהים לשם ולסוג של המזהה המקומי האחרון שהיה פעיל במרשם שצוין.
DBG_SET_PROLOGUE_END 0x07 (none) מגדיר את המרשם של מכונת המצב prologue_end, ומציין שצריך להתייחס לרשומת המיקום הבאה שנוספה כסוף של תחילת השיטה (מקום מתאים לנקודת עצירה בקוד של השיטה). כל קוד פעולה מיוחד (>= 0x0a) מנקה את המרשם prologue_end.
DBG_SET_EPILOGUE_BEGIN 0x08 (none) מגדיר את המרשם של מכונת המצב epilogue_begin, ומציין שצריך להתייחס לרשומת המיקום הבאה שתתווסף כתחילת חותמת הסיום של השיטה (מקום מתאים להשעיית הביצוע לפני יציאה מהשיטה). כל קוד פעולה מיוחד (>= 0x0a) מנקה את המרשם epilogue_begin.
DBG_SET_FILE 0x09 uleb128p1 name_idx name_idx: אינדקס המחרוזת של שם קובץ המקור. אם הוא לא ידוע, הערך יהיה NO_INDEX. מציין שכל הרשומות הבאות של מספרי השורות יפנו לשם של קובץ המקור הזה, במקום לשם ברירת המחדל שצוין ב-code_item.
Opcodes מיוחדים 0x0a…0xff (none) מקדמת את המרשמים line ו-address, פולטת רשומת מיקום ומאפסת את prologue_end ו-epilogue_begin. תיאור מופיע בהמשך.

קודי פעולה מיוחדים

קוד הפקודה עם ערכים בין 0x0a ל-0xff (כולל) מעביר את הרישומים line ו-address בקטנה ואז פולט רשומה חדשה בטבלת המיקומים. הנוסחה לחישוב העלייה היא:

DBG_FIRST_SPECIAL = 0x0a  // the smallest special opcode
DBG_LINE_BASE   = -4      // the smallest line number increment
DBG_LINE_RANGE  = 15      // the number of line increments represented

adjusted_opcode = opcode - DBG_FIRST_SPECIAL

line += DBG_LINE_BASE + (adjusted_opcode % DBG_LINE_RANGE)
address += (adjusted_opcode / DBG_LINE_RANGE)

annotations_directory_item

הפניה מ-class_def_item

מופיע בקטע 'נתונים'

התאמה: 4 בייטים

שם פורמט תיאור
class_annotations_off uint הפרש מתחילת הקובץ אל ההערות שנוצרו ישירות על הכיתה, או 0 אם אין בכיתה הערות ישירות. אם הערך של ההיסט שונה מאפס, הוא צריך להצביע למיקום בקטע data. הפורמט של הנתונים מצוין ב-annotation_set_item בהמשך.
fields_size uint מספר השדות שנוספה להם הערה על ידי הפריט הזה
annotated_methods_size uint מספר השיטות שנוספה להן הערה על ידי הפריט הזה
annotated_parameters_size uint מספר רשימות הפרמטרים של השיטות שנוספה להן הערה על ידי הפריט הזה
field_annotations field_annotation[fields_size] (אופציונלי) רשימה של הערות שמשויכות לשדות. האלמנטים ברשימה חייבים להיות ממויינים בסדר עולה לפי field_idx.
method_annotations method_annotation[methods_size] (אופציונלי) רשימה של הערות לשיטות המשויכות. האלמנטים ברשימה חייבים להיות ממויינים בסדר עולה לפי method_idx.
parameter_annotations parameter_annotation[parameters_size] (אופציונלי) רשימה של הערות של פרמטרים משויכים של שיטות. צריך למיין את הרכיבים של הרשימה בסדר עולה לפי method_idx.

הערה: כל המופעים של field_id ו-method_id של הרכיבים חייבים להפנות לאותה כיתה מגדירה.

הפורמט של field_annotation

שם פורמט תיאור
field_idx uint חיפוש ברשימה field_ids כדי לזהות את השדה שאליו מצורפת ההערה
annotations_off uint הזזה מתחילת הקובץ אל רשימת ההערות של השדה. ההיסט צריך להיות למיקום בקטע data. הפורמט של הנתונים מצוין ב-annotation_set_item בהמשך.

פורמט method_annotation

שם פורמט תיאור
method_idx uint חיפוש ברשימה method_ids כדי לזהות את השיטה שרוצים להוסיף לה הערה
annotations_off uint מההתחלה של הקובץ ועד לרשימת ההערות של השיטה. ההיסט צריך להיות למיקום בקטע data. הפורמט של הנתונים מצוין ב-annotation_set_item בהמשך.

הפורמט של parameter_annotation

שם פורמט תיאור
method_idx uint חיפוש ברשימה method_ids כדי למצוא את הזהות של השיטה שאליה מצורפות הערות על הפרמטרים
annotations_off uint הזזה מתחילת הקובץ אל רשימת ההערות של פרמטרים של שיטות. ההיסט צריך להיות למיקום בקטע data. הפורמט של הנתונים מצוין ב-annotation_set_ref_list בהמשך.

annotation_set_ref_list

הפניה מ-parameter_annotations_item

מופיע בקטע 'נתונים'

התאמה: 4 בייטים

שם פורמט תיאור
size uint גודל הרשימה, בכניסות
רשימה annotation_set_ref_item[size] הרכיבים של הרשימה

הפורמט annotation_set_ref_item

שם פורמט תיאור
annotations_off uint הזזה מתחילת הקובץ אל קבוצת ההערות שצוינה, או 0 אם אין הערות לאלמנט הזה. אם הערך של ההיסט שונה מאפס, הוא צריך להצביע למיקום בקטע data. הפורמט של הנתונים מצוין ב-annotation_set_item בהמשך.

annotation_set_item

הפניה מ-annotations_directory_item,‏ field_annotations_item,‏ method_annotations_item ו-annotation_set_ref_item

מופיע בקטע 'נתונים'

התאמה: 4 בייטים

שם פורמט תיאור
size uint גודל הקבוצה, בכניסות
רשומות annotation_off_item[size] הרכיבים של הקבוצה. האלמנטים חייבים להיות ממוינים בסדר עולה לפי type_idx.

פורמט annotation_off_item

שם פורמט תיאור
annotation_off uint הזזה מתחילת הקובץ להערה. ההיסט צריך להיות למיקום בקטע data, והפורמט של הנתונים במיקום הזה מצוין ב-annotation_item שבהמשך.

annotation_item

הפניה מ-annotation_set_item

מופיע בקטע 'נתונים'

התאמה: ללא (יישור לפי בייטים)

שם פורמט תיאור
חשיפה ubyte רמת החשיפה המיועדת של ההערה הזו (ראו בהמשך)
הערה encoded_annotation תוכן של הערות קודקדו, בפורמט שמתואר בקטע 'encoded_annotation format' בקטע 'encoded_value encoding' למעלה.

ערכי הרשאות הגישה

אלה האפשרויות בשדה visibility ב-annotation_item:

שם ערך תיאור
VISIBILITY_BUILD 0x00 מיועדים להיות גלויים רק בזמן ה-build (למשל, במהלך הידור של קוד אחר)
VISIBILITY_RUNTIME 0x01 מיועדים להיות גלויים בזמן הריצה
VISIBILITY_SYSTEM 0x02 נועדו להיות גלויים במהלך זמן הריצה, אבל רק למערכת הבסיסית (ולא לקוד משתמש רגיל)

encoded_array_item

הפניה מ-class_def_item

מופיע בקטע 'נתונים'

התאמה: ללא (יישור לפי בייטים)

שם פורמט תיאור
ערך encoded_array ביטים שמייצגים את ערך המערך המקודד, בפורמט שצוין בשדה encoded_array Format בקטע encoded_value Encoding למעלה.

hiddenapi_class_data_item

הקטע הזה מכיל נתונים על ממשקים מוגבלים שבהם כל כיתה משתמשת.

הערה: התכונה של ה-API המוסתר הוצגה ב-Android 10.0 והיא רלוונטית רק לקובצי ה-DEX של הכיתות בנתיב הכיתות של האתחול. רשימת הדגלים שמתוארת בהמשך עשויה להתארך בגרסאות עתידיות של Android. מידע נוסף זמין במאמר הגבלות על ממשקים שאינם SDK.

שם פורמט תיאור
size uint הגודל הכולל של הקטע
קיזוזים uint[] מערך של סטיות (offsets) שנוספו לאינדקס על ידי class_idx. אם הערך ב-array הוא אפס ב-index class_idx, המשמעות היא שאין נתונים עבור class_idx הזה, או שכל הדגלים של ה-API המוסתרים הם אפס. אחרת, הערך של רשומת המערך הוא לא אפס והוא מכיל את הזזת האופרטור (offset) מתחילת הקטע למערך של דגלים מוסתרים של API עבור class_idx הזה.
דגלים uleb128[] מערכי מחרוזות של דגלים מוסתרים של ממשקי API לכל כיתה. בטבלה הבאה מתוארים ערכי הדגל האפשריים. הדגלים מקודדים באותו סדר שבו השדות והשיטות מקודדים בנתוני הכיתה.

סוגי דגלים של הגבלות:

שם ערך תיאור
רשימת היתרים 0 ממשקים שאפשר להשתמש בהם באופן חופשי ונתמכים כחלק ממסגרת Android הרשמית, Package Index.
רשימה אפורה 1 ממשקים שאינם ב-SDK שאפשר להשתמש בהם ללא קשר לרמת ה-API לטירגוט של האפליקציה.
הוסף לרשימה השחורה 2 ממשקים שאינם ב-SDK, שלא ניתן להשתמש בהם ללא קשר לרמת ה-API לטירגוט של האפליקציה. הגישה לאחד מהממשקים האלה גורמת לשגיאת זמן ריצה.
greylist‑max‑o 3 ממשקים שאינם ב-SDK שאפשר להשתמש בהם ב-Android מגרסה 8.x ומטה, אלא אם הם מוגבלים.
greylist‑max‑p 4 ממשקים שאינם SDK שאפשר להשתמש בהם ב-Android 9.x, אלא אם הם מוגבלים.
greylist‑max‑q 5 ממשקים שאינם SDK שאפשר להשתמש בהם ב-Android 10.x, אלא אם הם מוגבלים.
greylist‑max‑r 6 ממשקים שאינם SDK שאפשר להשתמש בהם ב-Android 11.x, אלא אם הם מוגבלים.

הערות מערכת

הערות מערכת משמשות לייצוג קטעים שונים של מידע רפלקטיבי על כיתות (וגם על שיטות ושדות). בדרך כלל, קוד לקוח (לא מערכת) ניגש למידע הזה באופן עקיף בלבד.

הערות מערכת מיוצגות בקובצי .dex בתור הערות שההרשאות הגישה שלהן מוגדרות לערך VISIBILITY_SYSTEM.

dalvik.annotation.AnnotationDefault

מופיע בשיטות בממשקי הערה

הערה AnnotationDefault מצורפת לכל ממשק הערה שרוצים לציין בו קישורי ברירת מחדל.

שם פורמט תיאור
ערך הערה קישורי ברירת המחדל של ההערה הזו, שמיוצגים כהערה מסוג זה. ההערה לא חייבת לכלול את כל השמות שמוגדרים בה. שמות חסרים פשוט לא יהיו להם ברירת מחדל.

dalvik.annotation.EnclosingClass

מופיע בכיתות

הערה EnclosingClass מצורפת לכל מחלקה שמוגדרת כחברה במחלקה אחרת, או כאנונימית אבל לא מוגדרת בגוף של method (למשל, מחלקה פנימית סינתטית). לכל כיתה עם ההערה הזו צריכה להיות גם הערה מסוג InnerClass. בנוסף, אסור לכלול בכיתה גם הערה מסוג EnclosingClass וגם הערה מסוג EnclosingMethod.

שם פורמט תיאור
ערך דרגה הכיתה שהכי קרובה לכיתה הזו מבחינה לקסיקלית

dalvik.annotation.EnclosingMethod

מופיע בכיתות

הערה EnclosingMethod מצורפת לכל כיתה שמוגדרת בגוף של שיטה. לכל כיתה עם ההערה הזו צריכה להיות גם הערה מסוג InnerClass. בנוסף, אסור שיהיו בכיתה גם הערה מסוג EnclosingClass וגם הערה מסוג EnclosingMethod.

שם פורמט תיאור
ערך שיטה השיטה שמתאימה ביותר להיקף הלקסיקלי של הכיתה

dalvik.annotation.InnerClass

מופיע בכיתות

הערה InnerClass מצורפת לכל כיתה שמוגדרת בהיקף הלקסיקלי של הגדרת כיתה אחרת. כל כיתה עם ההערה הזו חייבת לכלול גם הערה מסוג EnclosingClass או הערה מסוג EnclosingMethod.

שם פורמט תיאור
שם מחרוזת השם הפשוט שהוצהר במקור של הכיתה הזו (לא כולל תחילית של חבילה). אם הכיתה הזו אנונימית, השם הוא null.
accessFlags INT דגלים של גישה שהוצהרו במקור על הכיתה (שעשויים להיות שונים מדגלים יעילים בגלל חוסר התאמה בין מודלים של ביצוע של שפת המקור לבין מכונה וירטואלית של היעד)

dalvik.annotation.MemberClasses

מופיע בכיתות

הערה MemberClasses מצורפת לכל כיתה שמצהירה על כיתות חברות. (כיתה חברת היא כיתה פנימית ישירה שיש לה שם).

שם פורמט תיאור
ערך Class[] מערך של כיתות החברים

dalvik.annotation.MethodParameters

מופיע בשיטות

הערה: ההערה הזו נוספה אחרי Android 7.1. המערכת תתעלם מהנוכחות שלו בגרסאות Android קודמות.

הערה MethodParameters היא אופציונלית, וניתן להשתמש בה כדי לספק מטא-נתונים של פרמטרים, כמו שמות פרמטרים ומשתני פונקציה.

אפשר להשמיט את ההערה מ-method או מ-constructor באופן בטוח אם המטא-נתונים של הפרמטר לא נדרשים במהלך זמן הריצה. אפשר להשתמש ב-java.lang.reflect.Parameter.isNamePresent() כדי לבדוק אם יש מטא-נתונים לפרמטר, ושיטות ההשתקפות המשויכות, כמו java.lang.reflect.Parameter.getName(), יחזרו להתנהגות ברירת המחדל בזמן הריצה אם המידע לא קיים.

כשכוללים מטא-נתונים של פרמטרים, המהדרים חייבים לכלול מידע על כיתות שנוצרו, כמו enums, כי המטא-נתונים של הפרמטרים כוללים את הקביעה אם הפרמטר הוא סינתטי או נדרש.

הערה מסוג MethodParameters מתארת רק פרמטרים נפרדים של שיטות. לכן, כדי לצמצם את גודל הקוד ולשפר את היעילות בסביבת זמן הריצה, המהדרים עשויים להשמיט את ההערה לגמרי לגבי קונסטרוקטורים ושיטות ללא פרמטרים.

המערכים שמתוארים בהמשך חייבים להיות באותו גודל כמו המבנה של method_id_item dex שמשויך לשיטה, אחרת תופיע הודעת השגיאה java.lang.reflect.MalformedParametersException בזמן הריצה.

כלומר: method_id_item.proto_idx -> proto_id_item.parameters_off -> type_list.size חייב להיות זהה ל-names().length ול-accessFlags().length.

מכיוון ש-MethodParameters מתאר את כל הפרמטרים הפורמליים של השיטה, גם אלה שלא הוגדרו במפורש או במשתמע בקוד המקור, ייתכן שהגודל של המערכי יכול להיות שונה מהחתימה או מנתוני המטא-נתונים האחרים שמבוססים רק על פרמטרים מפורשים שהוגדרו בקוד המקור. MethodParameters לא יכלול גם מידע על פרמטרים של מקבלים של הערות לסוגים שלא קיימים בחתימת השיטה בפועל.

שם פורמט תיאור
שמות String[] השמות של הפרמטרים הפורמליים של השיטה המשויכת. המערך לא יכול להיות null, אבל הוא חייב להיות ריק אם אין פרמטרים רשמיים. אם לפרמטר הפורמלי עם האינדקס הזה אין שם, הערך במערך חייב להיות null.
אם מחרוזות של שמות פרמטרים ריקות או מכילות את התו '.', ';', '[' או '/', תושלח הודעת השגיאה java.lang.reflect.MalformedParametersException בזמן הריצה.
accessFlags int[] דגלים של גישה של הפרמטרים הפורמליים של השיטה המשויכת. המערך לא יכול להיות null, אבל הוא חייב להיות ריק אם אין פרמטרים פורמליים.
הערך הוא מסכת ביט עם הערכים הבאים:
  • 0x0010 : סופי, הפרמטר הוגדר כסופי
  • 0x1000 : מלאכותי, הפרמטר הוצג על ידי המהדר
  • 0x8000 : חובה, הפרמטר הוא סינתטי אבל גם משתמע מפרטי השפה
אם יהיו ביטים שמוגדרים מחוץ לקבוצה הזו, תופיע הודעת השגיאה java.lang.reflect.MalformedParametersException בסביבת זמן הריצה.

dalvik.annotation.Signature

מופיע בכיתות, בשדות ובשיטות

הערה מסוג Signature מצורפת לכל כיתה, שדה או שיטה שמוגדרים במונחים של טיפוס מורכב יותר שלא ניתן לייצג באמצעות type_id_item. הפורמט .dex לא מגדיר את הפורמט לחתימות, אלא רק מאפשר לייצג את כל החתימות שנדרשות בשפת המקור כדי להטמיע בהצלחה את הסמנטיקה של השפה הזו. לכן, בדרך כלל חתימות לא מנותחות (או מאומתות) על ידי הטמעות של מכונות וירטואליות. החתימה מועברת ל-API ולכלים ברמה גבוהה יותר (כמו מניפולי קוד). לכן, כל שימוש בחתימה צריך להיכתב כך שלא יתבסס על הנחה שתקבלו רק חתימות תקינות, ויש להימנע מכך באופן מפורש כדי להימנע מהאפשרות לקבל חתימה לא תקינה מבחינה תחבירית.

מאחר שמחרוזות חתימה נוטים להכיל הרבה תוכן כפול, הערה מסוג Signature מוגדרת כמערך של מחרוזות, שבהן רכיבים כפולים מתייחסים באופן טבעי לאותו נתון בסיסי, והחתימה נחשבת לשרשור של כל המחרוזות במערך. אין כללים לגבי אופן הפירוק של חתימה למחרוזות נפרדות. הדבר תלוי לחלוטין בכלים שיוצרים את קובצי ה-.dex.

שם פורמט תיאור
ערך String[] החתימה של הכיתה או המשתנה, כמערך של מחרוזות שצריך לשרשור יחד

dalvik.annotation.Throws

מופיע בשיטות

הערה מסוג Throws מצורפת לכל שיטה שמוצהרת כמייצרת סוג אחד או יותר של חריגות.

שם פורמט תיאור
ערך Class[] מערך סוגי החריגות שהופעלו