פורמט קובץ הפעלה של Dalvik

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

מדריך לסוגים

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

LEB128

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

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

תרשים ברמת הסיביות של ערך LEB128 באורך שני בייטים
הבייט הראשון הבייט השני
1 ‫bit6 bit5 bit4 bit3 bit2 bit1 ‫bit0 0 bit13 bit12 bit11 bit10 ‫bit9 bit8 ‫bit7

הווריאנט 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 (לפי אינדקס proto_id) הוא הסדר הזניח. הרשימה לא יכולה להכיל רשומות כפולות.
class_defs class_def_item[] רשימת הגדרות הכיתות. הסדר של המחלקות צריך להיות כזה שהמחלקה העל והממשקים המיושמים של מחלקה נתונה יופיעו ברשימה לפני המחלקה המפנה. בנוסף, אסור להגדיר את אותו שם של מחלקה יותר מפעם אחת ברשימה.
call_site_ids call_site_id_item[] רשימת מזהי אתרים לשיחות. אלה מזהים של כל האתרים שמוזכרים בקובץ הזה, בין אם הם מוגדרים בקובץ ובין אם לא. הרשימה הזו צריכה להיות ממוינת בסדר עולה לפי call_site_off.
method_handles method_handle_item[] רשימת method handles. רשימה של כל ה-method handles שאליהם יש הפניה בקובץ הזה, בין אם הם מוגדרים בקובץ ובין אם לא. הרשימה הזו לא ממוינת ועשויות להיות בה כפילויות, שיתאימו באופן לוגי למופעים שונים של טיפול בשיטות.
נתונים 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) ובייט null ("\0" או 0x00) כדי לעזור בזיהוי של סוגים מסוימים של נזק. הערך גם מקודד מספר גרסת פורמט כשלוש ספרות עשרוניות, שאמורות לגדול באופן מונוטוני לאורך זמן ככל שהפורמט מתפתח.

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

הערה: התמיכה בגרסה 041 של הפורמט נוספה בגרסה Android 16, עם תמיכה בפורמט המאגר.

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

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

הערה: התמיכה בגרסה 038 של הפורמט נוספה בגרסה Android 8.0. בגרסה 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: global to defining class 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     הארגומנט האחרון צריך להיות מטופל כארגומנט 'rest' על ידי הקומפיילר
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 מקודדת בפורמט של שני בייטים.
  • בדומה לפרשנות הסטנדרטית בשפת C, בייט null רגיל (ערך 0) מציין את סוף המחרוזת.

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

הפורמט של encoded_array

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

הפורמט של encoded_annotation

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

הפורמט של רכיב ההערה

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

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

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

SimpleName

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

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

שם החבר

משמש את 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 בייטים

שם פורמט תיאור
קסם ubyte[8] = DEX_FILE_MAGIC ערך קסום. פרטים נוספים מופיעים בדיון שלמעלה בקטע DEX_FILE_MAGIC.
סכום ביקורת uint סכום ביקורת מסוג adler32 של שאר הקובץ (הכול חוץ מ- magic והשדה הזה); משמש לזיהוי קובץ פגום
חתימה ubyte[20] חתימת 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 ההיסט מתחילת הקובץ לרשימת הגדרות המחלקה, או 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 גודל הרשימה, במספר הרשומות
list 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

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

התאמה: none (byte-aligned)

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

הערה: מותר להשתמש במחרוזת שכוללת יחידות קוד חלופיות של UTF-16 (כלומר, U+d800U+dfff) בקידוד (encoded) UTF-16, בנפרד או לא לפי הסדר הרגיל של קידוד 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 ‫index into the type_ids list for the return type of this prototype
parameters_off uint ההיסט מתחילת הקובץ עד לרשימת סוגי הפרמטרים בפרוטוטייפ הזה, או 0 אם בפרוטוטייפ הזה אין פרמטרים. אם ההיסט הזה שונה מאפס, הוא צריך להיות בקטע data, והנתונים שם צריכים להיות בפורמט שצוין ב-"type_list" למטה. בנוסף, ברשימה לא צריכה להיות הפניה לסוג void.

field_id_item

מופיע בקטע field_ids

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

שם פורמט תיאור
class_idx ushort אינדקס ברשימה type_ids של מגדיר השדה הזה. המאפיין הזה חייב להיות מסוג class, ולא מסוג מערך או מסוג פרימיטיבי.
type_idx ushort אינדקס ברשימה type_ids של סוג השדה
name_idx uint ‫index into the string_ids list for the name of this field. המחרוזת חייבת להיות תואמת לתחביר של MemberName, שמוגדר למעלה.

method_id_item

מופיע בקטע method_ids

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

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

class_def_item

מופיע בקטע class_defs

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

שם פורמט תיאור
class_idx uint אינדקס לתוך רשימת type_ids של הכיתה הזו. המאפיין הזה חייב להיות מסוג class, ולא מסוג מערך או מסוג פרימיטיבי.
access_flags uint דגלי גישה לכיתה (public,‏ final וכו'). פרטים נוספים מופיעים בקטע access_flagsהגדרות.
superclass_idx uint האינדקס ברשימה type_ids של מחלקת העל, או הערך הקבוע NO_INDEX אם למחלקה הזו אין מחלקת על (כלומר, זו מחלקת בסיס כמו Object). אם השדה הזה קיים, הוא חייב להיות מסוג מחלקה, ולא מסוג מערך או מסוג פרימיטיבי.
interfaces_off uint ההיסט מתחילת הקובץ עד לרשימת הממשקים, או 0 אם אין ממשקים. ההיסט הזה צריך להיות בקטע data, והנתונים שם צריכים להיות בפורמט שצוין בקטע type_list שבהמשך. כל אחד מהאלמנטים ברשימה חייב להיות מסוג מחלקה (לא מערך או סוג פרימיטיבי), ואסור שיהיו כפילויות.
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

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

התאמה: none (byte aligned)

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

  1. ‫method handle שמייצג את שיטת ה-bootstrap linker‏ (VALUE_METHOD_HANDLE).
  2. שם של שיטה שצריך לפתור באמצעות bootstrap linker ‏ (VALUE_STRING).
  3. סוג ה-method שמתאים לסוג של שם ה-method שצריך לפתור (VALUE_METHOD_TYPE).

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

לשיטת ה-handle שמייצגת את שיטת ה-bootstrap linker צריך להיות סוג החזרה 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 הוא שדה סטטי setter (רכיב גישה)
METHOD_HANDLE_TYPE_STATIC_GET 0x01 ‫Method handle is a static field getter (accessor)
METHOD_HANDLE_TYPE_INSTANCE_PUT 0x02 ‫Method handle הוא שדה מופע של setter (אחזור נתונים)
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 is an interface method invoker

class_data_item

הפניה מ-class_def_item

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

התאמה: none (byte-aligned)

שם פורמט תיאור
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 ההיסט מתחילת הקובץ למבנה הקוד של ה-method הזה, או 0 אם ה-method הזה הוא abstract או native. ההיסט צריך להיות למיקום בקטע data. הפורמט של הנתונים מוגדר על ידי "code_item" בהמשך.

type_list

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

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

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

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

type_item format

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

code_item

הפניה מ-encoded_method

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

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

שם פורמט תיאור
registers_size ushort מספר הרגיסטרים שנעשה בהם שימוש בקוד הזה
ins_size ushort מספר המילים של הארגומנטים הנכנסים לשיטה שאליה הקוד הזה מתייחס
outs_size ushort מספר המילים של מרחב הארגומנטים היוצא שנדרש לקוד הזה להפעלת שיטה
tries_size ushort מספר ה-try_items במופע הזה. אם הערך שמוגדר הוא לא אפס, הם מופיעים כמערך tries מיד אחרי insns במופע הזה.
debug_info_off uint ההיסט מתחילת הקובץ לרצף של פרטי הניפוי (מספרי שורות + פרטים על משתנים מקומיים) של הקוד הזה, או 0 אם פשוט אין פרטים. אם ההיסט שונה מאפס, הוא צריך להיות במיקום בקטע data. הפורמט של הנתונים מפורט בקטע debug_info_item שבהמשך.
insns_size uint הגודל של רשימת ההוראות, ביחידות קוד של 16 ביט
insns ushort[insns_size] מערך בפועל של קוד בייט. הפורמט של הקוד במערך insns מפורט במסמך הנלווה Dalvik bytecode. הערה: למרות שההגדרה היא מערך של ushort, יש כמה מבנים פנימיים שמעדיפים יישור של ארבעה בייטים. בנוסף, אם זה קורה בקובץ עם החלפת סדר בתים, ההחלפה מתבצעת רק במופעים של ushort ולא במבנים הפנימיים הגדולים יותר.
padding ushort (אופציונלי) = 0 שני בייטים של ריפוד כדי ש-tries יהיה מיושר לארבעה בייטים. האלמנט הזה מופיע רק אם tries_size שונה מאפס ו-insns_size הוא מספר אי-זוגי.
מנסה מידת הפריט [tries_size](אופציונלי) מערך שמציין איפה בקוד נתפסים חריגים ואיך לטפל בהם. האלמנטים במערך לא יכולים להיות חופפים בטווח, והם צריכים להיות מסודרים מהכתובת הנמוכה לכתובת הגבוהה. האלמנט הזה מופיע רק אם הערך של tries_size הוא לא אפס.
רכיבי handler encoded_catch_handler_list (אופציונלי) בייטים שמייצגים רשימה של רשימות של סוגי חריגים וכתובות של מטפלים משויכים. לכל 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 גודל הרשימה הזו, במספר הרשומות
list encoded_catch_handler[handlers_size] רשימה בפועל של רשימות handler, שמוצגת ישירות (לא כהיסטים), ומשורשרת ברצף

הפורמט של encoded_catch_handler

שם פורמט תיאור
size sleb128 מספר סוגי התפיסה ברשימה הזו. אם הערך לא חיובי, הוא יהיה שווה לערך השלילי של מספר סוגי ה-catch, ואחרי ה-catch יופיע handler של catch-all. לדוגמה: A size of 0 means that there is a catch-all but no explicitly typed catches. הערך size של 2 מציין שיש שני תנאי catch עם הקלדה מפורשת, ואין תנאי catch כללי. ‫size of -1 פירושו שיש כתובת אחת עם הקלדה שגויה וכתובת אחת עם כלל.
רכיבי handler encoded_type_addr_pair[abs(size)] זרם של abs(size) פריטים מקודדים, אחד לכל סוג שנתפס, בסדר שבו הסוגים צריכים להיבדק.
catch_all_addr uleb128 (אופציונלי) כתובת bytecode של ה-handler של כתובת מסלקת דואר. האלמנט הזה מופיע רק אם הערך של size הוא לא חיובי.

הפורמט של encoded_type_addr_pair

שם פורמט תיאור
type_idx uleb128 ‫index into the type_ids list for the type of the exception to catch
addr uleb128 כתובת ה-bytecode של ה-exception handler המשויך

debug_info_item

הפניה מ-code_item

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

התאמה: none (byte-aligned)

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

מכונת המצבים מורכבת מחמישה אוגרים. ‫address register מייצג את ההיסט של ההוראה ב-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: רישום שיכיל את המשתנה local
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: register שיכיל את המידע המקומי
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: register that contained local מסמן משתנה מקומי שפעיל כרגע כמשתנה שלא נמצא בהיקף בכתובת הנוכחית
DBG_RESTART_LOCAL 0x06 uleb128 register_num register_num: צריך להירשם כדי להפעיל מחדש מגדיר מחדש משתנה מקומי בכתובת הנוכחית. השם והסוג זהים לאלה של הלוקאל האחרון שהיה פעיל ברשם שצוין.
DBG_SET_PROLOGUE_END 0x07 (none) מגדיר את הרגיסטר של מכונת המצבים prologue_end, כדי לציין שערך הכניסה הבא למיקום שנוסף צריך להיחשב כסוף של הקדמה של שיטה (מקום מתאים לנקודת עצירה של שיטה). הרישום prologue_end מתבצע על ידי כל קוד פעולה מיוחד (>= 0x0a).
DBG_SET_EPILOGUE_BEGIN 0x08 (none) מגדיר את epilogue_beginהרישום של מכונת המצבים, ומציין שרשומה של מיקום הבא שנוספת צריכה להיחשב כהתחלה של אפילוג של שיטה (מקום מתאים להשהיית הביצוע לפני היציאה מהשיטה). הרישום epilogue_begin מתבטל על ידי כל קוד פעולה מיוחד (>= 0x0a).
DBG_SET_FILE 0x09 uleb128p1 name_idx name_idx: אינדקס המחרוזת של שם קובץ המקור; אם לא ידועNO_INDEX מציין שכל הערכים הבאים של מספרי השורות מתייחסים לשם קובץ המקור הזה, במקום לשם ברירת המחדל שצוין ב-code_item
Special 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 גודל הרשימה, במספר הרשומות
list annotation_set_ref_item[size] אלמנטים ברשימה

‫annotation_set_ref_item format

שם פורמט תיאור
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

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

התאמה: none (byte-aligned)

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

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

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

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

encoded_array_item

הפניה מ-class_def_item

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

התאמה: none (byte-aligned)

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

hiddenapi_class_data_item

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

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

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

סוגי דגלי הגבלה:

שם ערך תיאור
רשימת היתרים 0 ממשקים שאפשר להשתמש בהם באופן חופשי ונתמכים כחלק מאינדקס החבילות של מסגרת Android שמתועדת באופן רשמי.
רשימה אפורה 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 מצורפת לכל מחלקה שמוגדרת בהיקף המילוני של ההגדרה של מחלקה אחרת. בכל כיתה שמופיעה בה ההערה הזו, צריך להופיע גם ההערה either EnclosingClass or EnclosingMethod.

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

dalvik.annotation.MemberClasses

מופיע בכיתות

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

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

dalvik.annotation.MethodParameters

מופיע בשיטות

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

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

אפשר להשמיט את ההערה משיטה או מ-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 לא יכלול גם מידע על פרמטרים של מקבל הערות מסוג שלא קיימים בחתימה של השיטה בפועל.

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

dalvik.annotation.Signature

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

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

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

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

dalvik.annotation.Throws

מופיע בשיטות

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

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