本文檔描述了.dex
檔案的佈局和內容,這些檔案用於保存一組類別定義及其關聯的附加資料。
類型指南
姓名 | 描述 |
---|---|
位元組 | 8 位元有符號整數 |
優位元組 | 8 位元無符號整數 |
短的 | 16 位元有符號 int,小端字節序 |
超短 | 16 位元無符號整數,小尾數 |
整數 | 32 位元有符號 int、小端字節序 |
單位 | 32 位元無符號整數,小尾數 |
長的 | 64 位元有符號 int、小端字節序 |
烏龍 | 64 位元無符號整數,小尾數 |
斯萊布128 | 有符號 LEB128,可變長度(見下文) |
烏萊布128 | 無符號 LEB128,可變長度(見下文) |
烏萊布128p1 | 無符號 LEB128 加1 ,可變長度(見下文) |
LEB128
LEB128(「 Little - Endian Base 128 」)是用於任意有符號或無符號整數量的可變長度編碼。此格式借用自DWARF3規範。在.dex
檔案中,LEB128 僅用於編碼 32 位元數量。
每個 LEB128 編碼值由一到五個位元組組成,它們一起代表一個 32 位元值。每個位元組都設定了其最高有效位,序列中的最後一個位元組除外,該位元組的最高有效位已清除。每個位元組的其餘七位元是有效負載,數量的最低有效七位元在第一個位元組中,接下來的七位元在第二個位元組中,依此類推。對於帶有符號的 LEB128 ( sleb128
),序列中最後一個位元組的最高有效負載位元將進行符號擴展以產生最終值。在無符號情況下 ( uleb128
),任何未明確表示的位元都被解釋為0
。
兩位元組 LEB128 值的位元圖 | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
第一個位元組 | 第二個位元組 | ||||||||||||||
1 | 位元6 | 位元5 | 位元4 | 位元3 | 位元2 | 位元1 | 位元0 | 0 | 位元13 | 位元12 | 位元11 | 位元10 | 位元9 | 位元8 | 位元7 |
變體uleb128p1
用來表示有符號值,其中表示的是編碼為uleb128
的值加一。這使得-1
(或被認為是無符號值0xffffffff
)的編碼 - 但沒有其他負數 - 成為一個字節,並且在所表示的數字必須為非負數或-1
(或0xffffffff
),並且不允許其他負值(或不太可能需要大的無符號值)。
以下是一些格式範例:
編碼序列 | 作為sleb128 | 作為uleb128 | 作為uleb128p1 |
---|---|---|---|
00 | 0 | 0 | -1 |
01 | 1 | 1 | 0 |
7f | -1 | 127 | 126 |
80 7f | -128 | 16256 | 16255 |
文件佈局
姓名 | 格式 | 描述 |
---|---|---|
標頭 | 標題項 | 標題 |
字串ID | 字串_id_項目[] | 字串標識符列表。這些是該檔案使用的所有字串的標識符,用於內部命名(例如類型描述符)或作為代碼引用的常數物件。此清單必須使用 UTF-16 代碼點值(不以區域設定敏感的方式)按字串內容排序,且不得包含任何重複的條目。 |
類型ID | 類型_id_項目[] | 類型標識符列表。這些是該文件引用的所有類型(類別、陣列或基本類型)的標識符,無論是否在文件中定義。此清單必須按string_id 索引排序,且不得包含任何重複的條目。 |
原型ID | 原型_id_項目[] | 方法原型識別碼列表。這些是該文件引用的所有原型的識別碼。此清單必須按返回類型(按type_id 索引)主順序排序,然後按參數列表(字典順序,各個參數按type_id 索引排序)排序。該清單不得包含任何重複的條目。 |
欄位ID | 字段_id_項目[] | 字段標識符列表。這些是該文件引用的所有欄位的標識符,無論是否在文件中定義。此清單必須進行排序,其中定義類型(按type_id 索引)是主要順序,欄位名稱(按string_id 索引)是中間順序,類型(按type_id 索引)是次要順序。該清單不得包含任何重複的條目。 |
方法ID | 方法_id_項目[] | 方法標識符列表。這些是該文件引用的所有方法的標識符,無論是否在文件中定義。此列表必須進行排序,其中定義類型(按type_id 索引)是主要順序,方法名稱(按string_id 索引)是中間順序,方法原型(按proto_id 索引)是次要順序。該清單不得包含任何重複的條目。 |
類別定義 | 類別定義項[] | 類別定義列表。必須對類別進行排序,以便給定類別的超類別和實作的介面早於引用類別出現在清單中。此外,同名類別的定義在清單中多次出現也是無效的。 |
呼叫站台 ID | 呼叫站點 ID 項目[] | 呼叫站點標識符列表。這些是該文件引用的所有呼叫網站的標識符,無論是否在文件中定義。該列表必須按call_site_off 的升序排序。 |
方法句柄 | 方法句柄項目[] | 方法處理列表。該文件引用的所有方法句柄的列表,無論是否在文件中定義。此清單未排序,並且可能包含邏輯上對應於不同方法句柄實例的重複項。 |
數據 | 優字節[] | 資料區域,包含上面列出的表格的所有支援資料。不同的項目有不同的對齊要求,如果需要的話,會在每個項目之前插入填充位元組以實現正確的對齊。 |
連結數據 | 優字節[] | 靜態連結檔案中使用的資料。本文檔未指定本節中資料的格式。此部分在未連結的檔案中為空,運行時實作可以根據需要使用它。 |
位元域、字串和常數定義
DEX_FILE_MAGIC
嵌入 header_item 中
常數數組/字串DEX_FILE_MAGIC
是必須出現在.dex
檔案開頭才能被辨識的位元組清單。該值有意包含換行符( "\n"
或0x0a
)和空位元組( "\0"
或0x00
),以協助偵測某些形式的損壞。該值還將格式版本號編碼為三位十進制數字,預計隨著格式的發展,該版本號會隨著時間的推移而單調增加。
ubyte[8] DEX_FILE_MAGIC = { 0x64 0x65 0x78 0x0a 0x30 0x33 0x39 0x00 } = "dex\n039\0"
注意: Android 9.0 版本中新增了對該格式039
版本的支持,其中引入了兩個新的字節碼const-method-handle
和const-method-type
。 (這些內容均在字節碼集表摘要中進行了描述。)在 Android 10 中,版本039
擴展了 DEX 檔案格式,以包含僅適用於引導類別路徑上的 DEX 檔案的隱藏 API 資訊。
注意: Android 8.0 版本中新增了對該格式038
版本的支援。版本038
新增了新的字節碼( invoke-polymorphic
和invoke-custom
)和方法句柄的資料。
注意: Android 7.0 版本中新增了對該格式037
版本的支援。在版本037
之前,大多數 Android 版本都使用版本035
的格式。 035
和037
版本唯一的差異是預設方法的增加和invoke
的調整。
注意:該格式的至少幾個早期版本已在廣泛使用的公共軟體版本中使用。例如,版本009
用於Android平台的M3版本(2007年11月至12月),版本013
用於Android平台的M5版本(2008年2月至3月)。在多個方面,這些早期版本的格式與本文檔中所述的版本有很大不同。
ENDIAN_CONSTANT 和 REVERSE_ENDIAN_CONSTANT
嵌入 header_item 中
常數ENDIAN_CONSTANT
用於指示在其中找到它的檔案的位元組順序。儘管標準.dex
格式是小尾數,但實作可以選擇執行位元組交換。如果實作遇到endian_tag
為REVERSE_ENDIAN_CONSTANT
而不是ENDIAN_CONSTANT
標頭,它將知道該檔案已從預期形式進行了位元組交換。
uint ENDIAN_CONSTANT = 0x12345678; uint REVERSE_ENDIAN_CONSTANT = 0x78563412;
沒有索引
嵌入在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_私人 | 0x2 | private :僅對定義類別可見 | private :僅對定義類別可見 | private :僅對定義類別可見 |
ACC_PROTECTED | 0x4 | protected :對包和子類別可見 | protected :對包和子類別可見 | protected :對包和子類別可見 |
ACC_靜態 | 0x8 | static :不是用外部this 引用建構的 | static :定義類別的全域 | static :不接受this 參數 |
ACC_FINAL | 0x10 | final :不可子類化 | final :構造後不可變 | final :不可覆蓋 |
ACC_SYNCHRONIZED | 0x20 | synchronized :在呼叫此方法時自動取得關聯鎖。注意:只有當 | ||
ACC_VOLATILE | 0x40 | volatile :特殊的存取規則有助於執行緒安全 | ||
ACC_BRIDGE | 0x40 | 橋接方法,由編譯器自動新增為類型安全橋接 | ||
ACC_TRANSIENT | 0x80 | transient :預設不儲存序列化 | ||
ACC_VARARGS | 0x80 | 最後一個參數應被編譯器視為「其餘」參數 | ||
ACC_NATIVE | 0x100 | native :以本機程式碼實現 | ||
ACC_介面 | 0x200 | interface :可多重實現的抽象類 | ||
ACC_摘要 | 0x400 | abstract :不能直接實例化 | abstract :此類未實現 | |
ACC_STRICT | 0x800 | strictfp :浮點運算的嚴格規則 | ||
ACC_SYNTHETIC | 0x1000 | 原始碼中沒有直接定義 | 原始碼中沒有直接定義 | 原始碼中沒有直接定義 |
ACC_註釋 | 0x2000 | 聲明為註解類 | ||
ACC_ENUM | 0x4000 | 聲明為枚舉類型 | 聲明為枚舉值 | |
(沒用過) | 0x8000 | |||
ACC_CONSTRUCTOR | 0x10000 | 建構函數方法(類別或實例初始值設定項) | ||
ACC_DECLARED_ 同步 | 0x20000 | 聲明synchronized 。注意:這對執行沒有影響(除了反映此標誌本身)。 |
InnerClass
註解中啟用,並且不得在class_def_item
中啟用。
修改後的UTF-8編碼
作為對更簡單的舊版支援的讓步, .dex
格式將其字串資料編碼為事實上的標準修改版 UTF-8 形式(以下稱為 MUTF-8)。此形式與標準 UTF-8 相同,除了:
- 僅使用一位元組、二位元組和三位元組編碼。
-
U+10000
…U+10ffff
範圍內的代碼點被編碼為代理對,每個代理對錶示為一個三位元組編碼值。 - 代碼點
U+0000
以兩位元組形式編碼。 - 純空位元組(值
0
)表示字串的結尾,這是標準 C 語言解釋。
上面的前兩條可以概括為:MUTF-8是UTF-16的一種編碼格式,而不是Unicode字元的更直接的編碼格式。
上面的最後兩個項目使得可以同時將代碼點U+0000
包含在字串中,並且仍然將其作為 C 風格的空終止字串進行操作。
然而, U+0000
的特殊編碼意味著,與普通 UTF-8 不同,在一對 MUTF-8 字串上呼叫標準 C 函數strcmp()
的結果並不總是表示不相等字串比較的正確簽章結果。當考慮排序(不僅僅是相等)時,比較 MUTF-8 字串的最直接方法是逐個字元解碼它們,並比較解碼後的值。 (但是,更聰明的實現也是可能的。)
有關字元編碼的更多信息,請參閱Unicode 標準。 MUTF-8 實際上更接近(相對不太知名的)編碼CESU-8 ,而不是 UTF-8 本身。
編碼值編碼
嵌入到annotation_element和encoded_array_item中
encoded_value
是(幾乎)任意分層結構資料的編碼片段。編碼既緊湊又易於解析。
姓名 | 格式 | 描述 |
---|---|---|
(值參數 << 5) |值類型 | 優位元組 | 指示緊接其後的value 的類型的位元組以及高位元三位中的可選澄清參數。請參閱下面的各種value 定義。大多數情況下, value_arg 編碼緊接在後的value 的長度(以位元組為單位),如(size - 1) ,例如0 表示該值需要 1 個位元組, 7 表示該值需要8 個位元組;然而,也存在如下所述的例外情況。 |
價值 | 優字節[] | 表示值的字節,長度可變,並且對於不同的value_type 字節有不同的解釋,但始終是小端字節序。有關詳細信息,請參閱下面的各種值定義。 |
值格式
類型名稱 | value_type | value_arg 格式 | value 格式 | 描述 |
---|---|---|---|---|
VALUE_BYTE | 0x00 | (無;必須為0 ) | 超字節[1] | 有符號的一位元組整數值 |
VALUE_SHORT | 0x02 | 大小 - 1 (0…1) | 位元組[大小] | 有符號兩位元組整數值,符號擴展 |
VALUE_CHAR | 0x03 | 大小 - 1 (0…1) | 位元組[大小] | 無符號兩位元組整數值,零擴展 |
VALUE_INT | 0x04 | 尺寸 - 1 (0…3) | 位元組[大小] | 有符號四位元組整數值,符號擴展 |
VALUE_LONG | 0x06 | 尺寸 - 1 (0…7) | 位元組[大小] | 有符號八位元組整數值,符號擴展 |
VALUE_FLOAT | 0x10 | 尺寸 - 1 (0…3) | 位元組[大小] | 四位元組位模式,向右零擴展,並解釋為 IEEE754 32 位元浮點數值 |
VALUE_DOUBLE | 0x11 | 尺寸 - 1 (0…7) | 位元組[大小] | 八位元組位模式,向右零擴展,並解釋為 IEEE754 64 位元浮點值 |
VALUE_METHOD_TYPE | 0x15 | 尺寸 - 1 (0…3) | 位元組[大小] | 無符號(零擴展)四位元組整數值,解釋為proto_ids 部分的索引並表示方法類型值 |
VALUE_METHOD_HANDLE | 0x16 | 尺寸 - 1 (0…3) | 位元組[大小] | 無符號(零擴展)四位元組整數值,解釋為method_handles 部分的索引並表示方法句柄值 |
VALUE_STRING | 0x17 | 尺寸 - 1 (0…3) | 位元組[大小] | 無符號(零擴展)四位元組整數值,解釋為string_ids 部分的索引並表示字串值 |
值類型 | 0x18 | 尺寸 - 1 (0…3) | 位元組[大小] | 無符號(零擴展)四位元組整數值,解釋為type_ids 部分的索引並表示反射類型/類別值 |
VALUE_FIELD | 0x19 | 尺寸 - 1 (0…3) | 位元組[大小] | 無符號(零擴展)四位元組整數值,解釋為field_ids 部分的索引並表示反射字段值 |
VALUE_METHOD | 0x1a | 尺寸 - 1 (0…3) | 位元組[大小] | 無符號(零擴展)四位元組整數值,解釋為method_ids 部分的索引並表示反射方法值 |
VALUE_ENUM | 0x1b | 尺寸 - 1 (0…3) | 位元組[大小] | 無符號(零擴展)四位元組整數值,解釋為field_ids 部分的索引並表示枚舉型別常數的值 |
VALUE_ARRAY | 0x1c | (無;必須為0 ) | 編碼數組 | 值的數組,採用下面的「 encoded_array format」指定的格式。 value 的大小隱含在編碼中。 |
VALUE_ANNOTATION | 0x1d | (無;必須為0 ) | 編碼註釋 | 子註釋,採用下面「 encoded_annotation format」指定的格式。 value 的大小隱含在編碼中。 |
VALUE_NULL | 0x1e | (無;必須為0 ) | (沒有任何) | null 參考值 |
VALUE_BOOLEAN | 0x1f | 布林值(0…1) | (沒有任何) | 一位值; 0 表示false , 1 表示true 。該位在value_arg 中表示。 |
編碼數組格式
姓名 | 格式 | 描述 |
---|---|---|
尺寸 | 烏萊布128 | 數組中的元素數量 |
價值觀 | 編碼值[大小] | 一系列按本節指定的格式按順序連接的size encoded_value 位元組序列。 |
編碼註釋格式
姓名 | 格式 | 描述 |
---|---|---|
類型idx | 烏萊布128 | 註釋的類型。這必須是類別(不是數組或基元)類型。 |
尺寸 | 烏萊布128 | 此註解中名稱-值映射的數量 |
元素 | 註釋元素[大小] | 註釋的元素,直接內聯表示(不是偏移量)。元素必須依string_id 索引升序排序。 |
註釋元素格式
姓名 | 格式 | 描述 |
---|---|---|
名稱_idx | 烏萊布128 | 元素名稱,表示為string_ids 部分的索引。該字串必須符合上面定義的MemberName的語法。 |
價值 | 編碼值 | 元素值 |
字串語法
.dex
檔案中有多種最終引用字串的項目。以下 BNF 樣式定義指示這些字串可接受的語法。
簡單名稱
SimpleName是其他事物名稱語法的基礎。 .dex
格式在這裡允許相當大的自由度(比大多數常見的源語言多得多)。簡而言之,簡單名稱由任何低位 ASCII 字母字元或數字、一些特定的低位 ASCII 符號以及大多數非控製字元、空格或特殊字元的非 ASCII 代碼點組成。從版本040
開始,該格式還允許空格字元(Unicode Zs
類別)。請注意,代理代碼點(在U+d800
… U+dfff
範圍內)本身不被視為有效的名稱字符,但 Unicode 補充字符是有效的(由SimpleNameChar規則的最終替代字符表示),並且它們應該在文件中表示為MUTF-8 編碼中的代理代碼點對。
簡單名稱→ | ||
SimpleNameChar ( SimpleNameChar )* | ||
簡單名稱字元→ | ||
'A' … 'Z' | ||
| | 'a' ... 'z' | |
| | '0' … '9' | |
| | ' ' | 自 DEX 版本 040 起 |
| | '$' | |
| | '-' | |
| | '_' | |
| | U+00a0 | 自 DEX 版本 040 起 |
| | U+00a1 … U+1fff | |
| | U+2000 … U+200a | 自 DEX 版本 040 起 |
| | U+2010 … U+2027 | |
| | U+202f | 自 DEX 版本 040 起 |
| | U+2030 … U+d7ff | |
| | U+e000 … U+ffef | |
| | U+10000 … U+10ffff |
成員名字
由 field_id_item 和 method_id_item 使用
MemberName是類別成員的名稱,成員是欄位、方法和內部類別。
會員姓名→ | |
簡單名稱 | |
| | '<' 簡單名稱'>' |
全類名
FullClassName是完全限定的類別名,包含可選的套件說明符,後面接著必需的名稱。
完整類別名稱→ | |
可選包前綴SimpleName | |
可選包前綴→ | |
(簡單名稱'/' )* |
類型描述符
由 type_id_item 使用
TypeDescriptor是任何類型的表示,包括基元、類別、陣列和void
。各個版本的涵義見下文。
類型描述符→ | |
'V' | |
| | 欄位類型描述符 |
字段類型描述符→ | |
非數組欄位類型描述符 | |
| | ( '[' * 1…255) NonArrayFieldTypeDescriptor |
非陣列欄位類型描述符→ | |
'Z' | |
| | 'B' |
| | 'S' |
| | 'C' |
| | 'I' |
| | 'J' |
| | 'F' |
| | 'D' |
| | 'L' 全類別名稱';' |
短描述符
由 proto_id_item 使用
ShortyDescriptor是方法原型的簡短形式表示,包括傳回類型和參數類型,但各種引用(類別或陣列)類型之間沒有區別。相反,所有引用類型都由單一'L'
字元表示。
短描述符→ | |
ShortyReturnType ( ShortyFieldType )* | |
ShortyReturnType → | |
'V' | |
| | 短字段類型 |
ShortyFieldType → | |
'Z' | |
| | 'B' |
| | 'S' |
| | 'C' |
| | 'I' |
| | 'J' |
| | 'F' |
| | 'D' |
| | 'L' |
類型描述符語義
這就是TypeDescriptor的每個變體的含義。
句法 | 意義 |
---|---|
V | void ;僅對返回類型有效 |
Z | boolean |
乙 | byte |
S | short |
C | char |
我 | int |
J | long |
F | float |
D | double |
L完全/合格/姓名; | 類別的fully.qualified.Name |
[描述符 | descriptor 符數組,可遞歸地用於數組數組,但超過 255 個維度是無效的。 |
項目和相關結構
本節包括.dex
檔案中可能出現的每個頂級項目的定義。
標題項
出現在標題部分
對齊方式:4位元組
姓名 | 格式 | 描述 |
---|---|---|
魔法 | ubyte[8] = DEX_FILE_MAGIC | 魔法值。有關更多詳細信息,請參閱上面“ DEX_FILE_MAGIC ”下的討論。 |
校驗和 | 單位 | 文件其餘部分的 adler32 校驗和(除了magic 和此欄位之外的所有內容);用於檢測文件損壞 |
簽名 | 超字節[20] | 文件其餘部分的 SHA-1 簽章(雜湊)(除了magic 、 checksum 和此欄位之外的所有內容);用於唯一識別文件 |
文件大小 | 單位 | 整個檔案的大小(包括檔案頭),以位元組為單位 |
標頭大小 | uint = 0x70 | 標頭(整個部分)的大小,以位元組為單位。這允許至少有限數量的向後/向前相容性而不會使格式無效。 |
位元組序標籤 | uint = ENDIAN_CONSTANT | 位元組序標記。有關更多詳細信息,請參閱上面“ ENDIAN_CONSTANT 和REVERSE_ENDIAN_CONSTANT ”下的討論。 |
連結大小 | 單位 | 連結部分的大小,如果該檔案不是靜態連結的,則為0 |
連結關閉 | 單位 | 從檔案開頭到連結部分的偏移量,如果link_size == 0 則為0 。偏移量(如果非零)應該是link_data 部分的偏移量。本文檔未指定所指向資料的格式;此標頭欄位(以及前一個)保留為鉤子以供運行時實現使用。 |
地圖關閉 | 單位 | 從檔案開頭到映射項的偏移量。偏移量必須非零,應該是data 部分的偏移量,資料應該採用下面「 map_list 」指定的格式。 |
字串 ID 大小 | 單位 | 字串標識符列表中的字串計數 |
字串_ids_關閉 | 單位 | 從檔案開頭到字串識別碼清單的偏移量,如果string_ids_size == 0 ,則為0 (誠然,這是一個奇怪的邊緣情況)。偏移量(如果非零)應位於string_ids 部分的開頭。 |
類型 ID 大小 | 單位 | 類型識別符清單中的元素計數,最多 65535 |
類型_ids_關閉 | 單位 | 從檔案開頭到類型標識符清單的偏移量,如果type_ids_size == 0 則為0 (誠然,這是一個奇怪的邊緣情況)。偏移量(如果非零)應位於type_ids 部分的開頭。 |
原型 ID 大小 | 單位 | 原型識別碼清單中的元素數量,最多 65535 |
proto_ids_off | 單位 | 從檔案開頭到原型識別符清單的偏移量,如果proto_ids_size == 0 則為0 (誠然,這是一個奇怪的邊緣情況)。偏移量(如果非零)應位於proto_ids 部分的開頭。 |
欄位 ID 大小 | 單位 | 字段標識符列表中的元素計數 |
字段 ID 關閉 | 單位 | 從檔案開頭到欄位識別碼清單的偏移量,如果field_ids_size == 0 0 則為0 。偏移量(如果非零)應位於field_ids 部分的開頭。 |
方法ID大小 | 單位 | 方法標識符列表中的元素計數 |
方法_ids_關閉 | 單位 | 從檔案開頭到方法標識符清單的偏移量,如果method_ids_size == 0 則為0 。偏移量(如果非零)應位於method_ids 部分的開頭。 |
類別定義大小 | 單位 | 類別定義清單中的元素計數 |
類別定義關閉 | 單位 | 從檔案開頭到類別定義清單的偏移量,如果class_defs_size == 0 則為0 (誠然,這是一個奇怪的邊緣情況)。偏移量(如果非零)應位於class_defs 部分的開頭。 |
數據大小 | 單位 | data 部分的大小(以位元組為單位)。必須是 sizeof(uint) 的偶數倍。 |
數據關閉 | 單位 | 從檔案開頭到data 部分開頭的偏移量。 |
地圖列表
出現在資料部分
引自 header_item
對齊方式:4位元組
這是文件全部內容的清單(依序)。它包含一些關於header_item
的冗餘,但旨在成為用於迭代整個文件的簡單形式。給定類型在映射中最多只能出現一次,但除了格式其餘部分隱含的限制之外,類型的出現順序沒有任何限制(例如, header
部分必須先出現,後跟string_ids
部分等)。此外,映射條目必須按初始偏移量排序,且不得重疊。
姓名 | 格式 | 描述 |
---|---|---|
尺寸 | 單位 | 清單的大小(以條目為單位) |
清單 | 地圖項目[大小] | 列表的元素 |
地圖項目格式
姓名 | 格式 | 描述 |
---|---|---|
類型 | 超短 | 物品類型;請參閱下表 |
沒用過 | 超短 | (沒用過) |
尺寸 | 單位 | 在指定偏移處找到的項目數的計數 |
抵銷 | 單位 | 從檔案開頭到相關項目的偏移量 |
類型代碼
物品種類 | 持續的 | 價值 | 項目大小(以位元組為單位) |
---|---|---|---|
標題項 | TYPE_HEADER_ITEM | 0x0000 | 0x70 |
字串_id_項目 | TYPE_STRING_ID_ITEM | 0x0001 | 0x04 |
類型_id_項目 | TYPE_TYPE_ID_ITEM | 0x0002 | 0x04 |
原型 ID 項目 | TYPE_PROTO_ID_ITEM | 0x0003 | 0x0c |
欄位 ID 項 | TYPE_FIELD_ID_ITEM | 0x0004 | 0x08 |
方法_id_項目 | TYPE_METHOD_ID_ITEM | 0x0005 | 0x08 |
類別定義項 | TYPE_CLASS_DEF_ITEM | 0x0006 | 0x20 |
呼叫站點 ID 項目 | TYPE_CALL_SITE_ID_ITEM | 0x0007 | 0x04 |
方法句柄項 | TYPE_METHOD_HANDLE_ITEM | 0x0008 | 0x08 |
地圖列表 | 類型地圖列表 | 0x1000 | 4 + (商品尺寸 * 12) |
類型清單 | 類型_類型_列表 | 0x1001 | 4 + (商品尺寸 * 2) |
註釋集引用列表 | TYPE_ANNOTATION_SET_REF_LIST | 0x1002 | 4 + (商品尺寸 * 4) |
註釋設定項 | TYPE_ANNOTATION_SET_ITEM | 0x1003 | 4 + (商品尺寸 * 4) |
類別資料項 | TYPE_CLASS_DATA_ITEM | 0x2000 | 隱含的;必須解析 |
代碼項 | 類型代碼項目 | 0x2001 | 隱含的;必須解析 |
字串資料項 | TYPE_STRING_DATA_ITEM | 0x2002 | 隱含的;必須解析 |
偵錯資訊項 | TYPE_DEBUG_INFO_ITEM | 0x2003 | 隱含的;必須解析 |
註釋項 | TYPE_ANNOTATION_ITEM | 0x2004 | 隱含的;必須解析 |
編碼數組項 | TYPE_ENCODED_ARRAY_ITEM | 0x2005 | 隱含的;必須解析 |
註釋目錄項 | TYPE_ANNOTATIONS_DIRECTORY_ITEM | 0x2006 | 隱含的;必須解析 |
隱藏的api_class_data_item | TYPE_HIDDENAPI_CLASS_DATA_ITEM | 0xF000 | 隱含的;必須解析 |
字串_id_項目
出現在 string_ids 部分
對齊方式:4位元組
姓名 | 格式 | 描述 |
---|---|---|
字串資料關閉 | 單位 | 從檔案開頭到此項目的字串資料的偏移量。偏移量應該是data 部分中的某個位置,並且資料應該採用下面“ string_data_item ”指定的格式。偏移量沒有對齊要求。 |
字串資料項
出現在資料部分
對齊方式:無(位元組對齊)
姓名 | 格式 | 描述 |
---|---|---|
utf16_大小 | 烏萊布128 | 該字串的大小,以 UTF-16 代碼單元表示(在許多系統中是「字串長度」)。也就是說,這是字串的解碼長度。 (編碼長度由0 位元組的位置暗示。) |
數據 | 優字節[] | 一系列 MUTF-8 代碼單元(也稱為八位元組、位元組),後面跟著一個值為0 的位元組。有關資料格式的詳細資訊和討論,請參閱上面的「MUTF-8(修改的 UTF-8)編碼」。注意:包含 UTF-16 代理代碼單元(即 |
類型_id_項目
出現在 type_ids 部分
對齊方式:4位元組
姓名 | 格式 | 描述 |
---|---|---|
描述符_idx | 單位 | 此類型的描述符字串的string_ids 清單中的索引。該字串必須符合上面定義的TypeDescriptor語法。 |
原型 ID 項目
出現在proto_ids部分
對齊方式:4位元組
姓名 | 格式 | 描述 |
---|---|---|
短IDX | 單位 | 該原型的短格式描述符字串的string_ids 列表中的索引。字串必須符合上面定義的ShortyDescriptor語法,並且必須對應於此項目的傳回類型和參數。 |
返回類型idx | 單位 | type_ids 清單中該原型傳回類型的索引 |
參數_關閉 | 單位 | 從檔案開頭到此原型的參數類型清單的偏移量,如果此原型沒有參數,則為0 。該偏移量如果非零,則應位於data 部分,並且其中的資料應採用下面"type_list" 指定的格式。此外,清單中不應引用void 類型。 |
欄位 ID 項
出現在 field_ids 部分
對齊方式:4位元組
姓名 | 格式 | 描述 |
---|---|---|
類別idx | 超短 | 此欄位定義者的type_ids 清單的索引。這必須是類別類型,而不是陣列或基本類型。 |
類型idx | 超短 | 此欄位類型的type_ids 清單的索引 |
名稱_idx | 單位 | string_ids 清單中的索引以取得該欄位的名稱。該字串必須符合上面定義的MemberName的語法。 |
方法_id_項目
出現在method_ids部分
對齊方式:4位元組
姓名 | 格式 | 描述 |
---|---|---|
類別idx | 超短 | 此方法的定義者的type_ids 清單的索引。這必須是類別或陣列類型,而不是原始類型。 |
原型idx | 超短 | 此方法原型的proto_ids 列表的索引 |
名稱_idx | 單位 | string_ids 清單中的索引以取得此方法的名稱。該字串必須符合上面定義的MemberName的語法。 |
類別定義項
出現在class_defs部分
對齊方式:4位元組
姓名 | 格式 | 描述 |
---|---|---|
類別idx | 單位 | 此類別的type_ids 列表的索引。這必須是類別類型,而不是陣列或基本類型。 |
訪問標誌 | 單位 | 類別的訪問標誌( public 、 final 等)。有關詳細信息,請參閱“ access_flags 定義”。 |
超類idx | 單位 | 超類別的type_ids 列表的索引,或者如果此類沒有超類別(即,它是根類,如Object ),則為常數值NO_INDEX 。如果存在,則它必須是類別類型,而不是陣列或基本類型。 |
介面關閉 | 單位 | 從檔案開頭到介面清單的偏移量,如果沒有則為0 。這個偏移量應該在data 部分,並且那裡的資料應該採用下面“ type_list ”指定的格式。清單中的每個元素都必須是類別類型(不是陣列或基本類型),並且不能有任何重複項。 |
來源檔案idx | 單位 | string_ids 清單中包含此類(至少是大部分)原始來源的檔案名稱的索引,或特殊值NO_INDEX 來表示缺少此資訊。任何給定方法的debug_info_item 都可能會覆寫該來源文件,但預期大多數類別僅來自一個來源文件。 |
註釋_關閉 | 單位 | 從文件開頭到此類的註釋結構的偏移量,如果此類上沒有註釋,則為0 。如果該偏移量非零,則應位於data 部分,並且其中的資料應採用下面「 annotations_directory_item 」指定的格式,所有項目都引用此類作為定義者。 |
類別資料關閉 | 單位 | 從檔案開頭到此項的關聯類別資料的偏移量,如果該類別沒有類別數據,則為0 。 (例如,如果此類是標記接口,則可能是這種情況。)偏移量如果非零,則應位於data 部分,並且那裡的資料應採用下面“ class_data_item ”指定的格式,所有項目都引用此類別作為定義者。 |
靜態值關閉 | 單位 | 從檔案開頭到static 欄位初始值清單的偏移量,如果沒有則為0 (且所有static 欄位都會使用0 或null 進行初始化)。這個偏移量應該在data 部分,並且那裡的資料應該採用下面「 encoded_array_item 」指定的格式。陣列的大小必須不大於該類別聲明的static 欄位的數量,且元素與static 欄位的對應順序與對應的field_list 中宣告的順序相同。每個數組元素的類型必須與其對應欄位的聲明類型相符。如果數組中的元素少於static 字段,則剩餘字段將使用適合類型的0 或null 進行初始化。 |
呼叫站點 ID 項目
出現在 call_site_ids 部分
對齊方式:4位元組
姓名 | 格式 | 描述 |
---|---|---|
呼叫站點關閉 | 單位 | 從檔案開頭到呼叫站點定義的偏移量。偏移量應該在資料部分,並且那裡的資料應該採用下面“call_site_item”指定的格式。 |
呼叫站點項目
出現在資料部分
對齊方式:無(位元組對齊)
call_site_item 是一個encoded_array_item,其元素對應到提供給引導連結器方法的參數。前三個參數是:
- 表示引導連結器方法的方法句柄 (VALUE_METHOD_HANDLE)。
- 引導連結器應解析的方法名稱 (VALUE_STRING)。
- 與要解析的方法名稱的型別相對應的方法型別 (VALUE_METHOD_TYPE)。
任何附加參數都是傳遞給引導連結器方法的常數值。這些參數按順序傳遞,沒有任何類型轉換。
表示引導連結器方法的方法句柄必須具有傳回類型java.lang.invoke.CallSite
。前三個參數類型是:
-
java.lang.invoke.Lookup
-
java.lang.String
-
java.lang.invoke.MethodType
任何附加參數的參數類型由它們的常數值決定。
方法句柄項
出現在method_handles部分
對齊方式:4位元組
姓名 | 格式 | 描述 |
---|---|---|
方法句柄類型 | 超短 | 方法句柄的類型;請參閱下表 |
沒用過 | 超短 | (沒用過) |
欄位或方法 ID | 超短 | 欄位或方法 ID 取決於方法句柄類型是存取器還是方法呼叫器 |
沒用過 | 超短 | (沒用過) |
方法句柄類型代碼
持續的 | 價值 | 描述 |
---|---|---|
METHOD_HANDLE_TYPE_STATIC_PUT | 0x00 | 方法句柄是靜態字段設定器(訪問器) |
METHOD_HANDLE_TYPE_STATIC_GET | 0x01 | 方法句柄是靜態欄位 getter(存取器) |
METHOD_HANDLE_TYPE_INSTANCE_PUT | 0x02 | 方法句柄是實例字段設定器(訪問器) |
METHOD_HANDLE_TYPE_INSTANCE_GET | 0x03 | 方法句柄是一個實例字段getter(訪問器) |
METHOD_HANDLE_TYPE_INVOKE_STATIC | 0x04 | 方法句柄是靜態方法呼叫程式 |
METHOD_HANDLE_TYPE_INVOKE_INSTANCE | 0x05 | 方法句柄是實例方法呼叫者 |
METHOD_HANDLE_TYPE_INVOKE_CONSTRUCTOR | 0x06 | 方法句柄是建構函式方法呼叫者 |
METHOD_HANDLE_TYPE_INVOKE_DIRECT | 0x07 | 方法句柄是直接方法呼叫者 |
METHOD_HANDLE_TYPE_INVOKE_INTERFACE | 0x08 | 方法句柄是介面方法呼叫者 |
類別資料項
引用自class_def_item
出現在資料部分
對齊方式:無(位元組對齊)
姓名 | 格式 | 描述 |
---|---|---|
靜態字段大小 | 烏萊布128 | 此項中定義的靜態欄位的數量 |
實例字段大小 | 烏萊布128 | 本項目中定義的實例字段數 |
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 或建構函數)方法表示為一系列編碼元素。該方法必須按method_idx 按越來越多的順序排序。 |
virtual_methods | encoded_method [virtual_methods_size] | 定義的虛擬(無static , private 或建構函數)表示為一系列編碼元素。除非該項目代表的類別覆蓋,否則此列表不應包括繼承的方法。該方法必須按method_idx 按越來越多的順序排序。虛擬方法的method_idx 必須與任何直接方法都不相同。 |
注意:所有元素的field_id
和method_id
實例必須參考相同的定義類別。
ENCODED_FIELD格式
姓名 | 格式 | 描述 |
---|---|---|
field_idx_diff | Uleb128 | 索引此欄位的身份(包括名稱和描述符)中的field_ids 列表,與列表中上一個元素的索引表示為差異。列表中第一個元素的索引直接表示。 |
訪問標誌 | Uleb128 | 該欄位的存取標誌( public , final 等)。有關詳細信息,請參見“ access_flags 定義”。 |
ENCODED_METHOD格式
姓名 | 格式 | 描述 |
---|---|---|
method_idx_diff | Uleb128 | 索引此方法的身份(包括名稱和描述符)的method_ids 列表,與列表中上一個元素的索引表示為差異。列表中第一個元素的索引直接表示。 |
訪問標誌 | Uleb128 | 該方法的訪問標誌( public , final 等)。有關詳細信息,請參見“ access_flags 定義”。 |
代碼關閉 | Uleb128 | 從檔案的開頭偏移到此方法的程式碼結構,或者如果此方法是abstract 或native 0 。偏移應為data 部分中的位置。資料的格式由下面的「 code_item 」指定。 |
type_list
從class_def_item和proto_id_item引用
出現在資料部分
對齊:4個位元組
姓名 | 格式 | 描述 |
---|---|---|
尺寸 | 單位 | 清單的大小,條目 |
清單 | type_item [size] | 列表的元素 |
type_item格式
姓名 | 格式 | 描述 |
---|---|---|
type_idx | 超短 | 索引到type_ids 列表 |
code_item
從encoded_method引用
出現在資料部分
對齊:4個位元組
姓名 | 格式 | 描述 |
---|---|---|
registers_size | 超短 | 此程式碼使用的暫存器數量 |
ins_size | 超短 | 傳入的論點的單字數量與該代碼適用的方法 |
outs_size | 超短 | 該程式碼需要用於方法呼叫所需的傳出參數空間的單字數量 |
tries_size | 超短 | 此實例的try_item s數。如果非零,則在此實例之後的insns 之後,它們顯示為tries 數組。 |
debug_info_off | 單位 | 從檔案的開頭偏移到此程式碼的偵錯資訊(行號 +本機變數資訊)序列,或如果沒有訊息,則為0 。偏移量(如果非零)應為data 部分中的位置。資料的格式由下面的「 debug_info_item 」指定。 |
insns_size | 單位 | 指令列表的尺寸,以16位元代碼單元為單位 |
insns | ushort [insns_size] | 字節碼的實際數組。 insns 數組中的程式碼格式由配套文件Dalvik字節碼指定。請注意,儘管這被定義為ushort 的數組,但有些內部結構更喜歡四位元組對齊。同樣,如果恰好在一個匯總的文件中,則僅在單一ushort 實例上而不是在較大的內部結構上進行交換。 |
填充 | ushort (可選) = 0 | 兩個位元組的填充物使tries 四位元組對齊。僅當tries_size 是非零,而insns_size 奇怪的情況下,此元素才存在。 |
嘗試 | try_item [tries_size] (可選) | 數組指示在程式碼異常中捕獲的位置以及如何處理它們。數組的元素必須在範圍內不重疊,從低位址到高位址。僅當tries_size 不為零時,此元素才存在。 |
處理程式 | encoded_catch_handler_list (可選) | 位元組代表捕獲類型和相關處理程序位址清單的清單。每個try_item 都有一個位元組偏移到此結構中。僅當tries_size 不為零時,此元素才存在。 |
try_item格式
姓名 | 格式 | 描述 |
---|---|---|
start_addr | 單位 | 啟動該條目涵蓋的程式碼區塊的位址。該位址是第一個涵蓋說明開始時的16位元代碼單元的計數。 |
insn_count | 超短 | 此條目涵蓋的16位元代碼單元的數量。涵蓋的最後一個程式碼單元(包含)是start_addr + insn_count - 1 。 |
handler_off | 超短 | 從關聯的encoded_catch_hander_list 到encoded_catch_handler 位元組中,以將位元組偏移。這必須是對encoded_catch_handler 的開始的偏移。 |
encoded_catch_handler_list格式
姓名 | 格式 | 描述 |
---|---|---|
尺寸 | Uleb128 | 此清單的大小,條目 |
清單 | encoded_catch_handler [handlers_size] | 直接表示的處理程序清單的實際清單(不是偏移),然後串聯 |
ENCODED_CATCH_HANDLER格式
姓名 | 格式 | 描述 |
---|---|---|
尺寸 | SLEB128 | 此清單中的捕獲類型數量。如果是非陽性的,則是捕獲類型數量的負數,捕獲器之後是捕獲的所有處理程序。例如: 0 的size 意味著有一個捕獲的東西,但沒有明確的鍵入。 size 為2 意味著有兩個明確輸入的捕獲量,沒有捕獲量。 -1 的size 意味著有一個鍵入的捕獲量和全部捕獲。 |
處理程式 | encoded_type_addr_pair [abs(size)] | abs(size) 編碼項目的流,每個捕獲的類型,都應按照測試類型進行測試。 |
catch_all_addr | ULEB128 (可選) | 封閉式處理程序的字節碼位址。僅當size 是非陽性時,此元素才存在。 |
ENCODED_TYPE_ADDR_PAIR格式
姓名 | 格式 | 描述 |
---|---|---|
type_idx | Uleb128 | 索引到type_ids 清單的擷取類型的類型 |
地址 | Uleb128 | 相關異常處理程序的字節碼位址 |
debug_info_item
從code_item引用
出現在資料部分
對齊:無(位元組對準)
每個debug_info_item
定義了一個矮人啟發的字節編碼狀態計算機,該機器在解釋時會發出位置表,並(可能)(可能) code_item
的局部變數資訊。序列從變數長度的標頭開始(其長度取決於方法參數的數量),後面是狀態電腦字節碼,並以DBG_END_SEQUENCE
BYTE結束。
州機器由五個登記冊組成。 address
暫存器表示16位元代碼單元中關聯的insns_item
中的指令偏移。 address
暫存器從每個debug_info
序列開始時從0
開始,只能單調增加。 line
暫存器表示應與狀態計算機發出的下一個位置表條目關聯的來源線號。它是在序列標頭中初始化的,並且可能會在正方向或負方向上變化,但絕不能小於1
。 source_file
暫存器表示行號參考的來源檔案。它被初始化為class_def_item
中source_file_idx
的值。其他兩個變量, prologue_end
和epilogue_begin
,是布爾旗(初始化為false
),表明是否應將下一個發出的位置視為方法序言或結語。狀態計算機還必須在每個暫存器中為DBG_RESTART_LOCAL
程式碼追蹤最後一個本機變數的名稱和類型。
標題如下:
姓名 | 格式 | 描述 |
---|---|---|
line_start | Uleb128 | 狀態計算機line 暫存器的初始值。不代表實際的位置條目。 |
parameters_size | Uleb128 | 編碼的參數名稱的數量。每個方法參數應該有一個,如果有的this ,則不包括實例方法。 |
parameter_names | uleb128p1 [parameters_size] | 方法參數名稱的字串索引。 NO_INDEX 的編碼值表示關聯參數沒有名稱。類型的描述符和簽名是從方法描述符和簽名中暗示的。 |
位元組代碼值如下:
姓名 | 價值 | 格式 | 論點 | 描述 |
---|---|---|---|---|
dbg_end_sequence | 0x00 | (沒有任何) | 終止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 ,則可以使用OPCODE DBG_START_LOCAL 更有效地表示相同的資料。)注意:有關處理簽名的警告,請參閱下面「 |
dbg_end_local | 0x05 | uleb128 register_num | register_num :註冊包含本地的註冊 | 在目前位址上標記目前壽命的局部變數範圍不超出範圍 |
dbg_restart_local | 0x06 | uleb128 register_num | register_num :註冊至重新啟動 | 在目前地址重新引入局部變數。名稱和類型與指定暫存器中的最後一個本機相同。 |
dbg_set_prologue_end | 0x07 | (沒有任何) | 設定prologue_end 狀態機暫存器,表示應將新增的下一個位置條目視為方法序言的結束(方法斷點的適當位置)。 prologue_end 暫存器由任何特殊( >= 0x0a )OpCode清除。 | |
dbg_set_epilogue_begin | 0x08 | (沒有任何) | 設定epilogue_begin 狀態機暫存器,表示應將新增的下一個位置條目視為方法結尾的開始(方法退出前暫停執行的適當位置)。 epilogue_begin 暫存器由任何特殊( >= 0x0a )OpCode清除。 | |
dbg_set_file | 0x09 | uleb128p1 name_idx | name_idx :來源檔案名稱的字串索引; NO_INDEX 如果未知 | 指示所有後續的行號條目都引用此來源檔案名,而不是code_item 中指定的預設名稱 |
特殊的Opcodes | 0x0a…0xff | (沒有任何) | 推line 和address 暫存器,排放位置輸入,並清除prologue_end 和epilogue_begin 。請參閱下文以取得說明。 |
特殊的Opcodes
具有0x0a
和0xff
(包含)的值的Opcodes少量移動行和address
line
,然後發出新的位置表條目。增量的公式如下:
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 | 單位 | 從文件的開頭偏移到直接在課堂上進行的註釋,或者如果類別沒有直接註釋,則偏移0 。偏移量(如果非零)應為data 部分中的位置。資料的格式由下面的「 annotation_set_item 」指定。 |
fields_size | 單位 | 該項目註解的欄位計數 |
Annotated_methods_size | 單位 | 該項目註釋的方法計數 |
Annotated_parameters_size | 單位 | 此項目註解的方法參數列表 |
field_annotations | field_annotation [fields_size] (可選) | 相關字段註釋列表。列表的元素必須按field_idx 進行越來越多的順序排序。 |
method_annotations | method_annotation [methods_size] (可選) | 相關方法註釋清單。列表的元素必須依照method_idx 進行越來越多的順序排序。 |
參數_annotations | parameter_annotation [parameters_size] (可選) | 相關方法參數註解清單。列表的元素必須依照method_idx 進行越來越多的順序排序。 |
注意:所有元素的field_id
和method_id
實例必須參考相同的定義類別。
field_annotation格式
姓名 | 格式 | 描述 |
---|---|---|
field_idx | 單位 | 索引到field_ids 列表,以註釋字段的身份 |
Annotations_off | 單位 | 從文件的開頭偏移到該欄位的註解清單。偏移應為data 部分中的位置。資料的格式由下面的「 annotation_set_item 」指定。 |
method_annotation格式
姓名 | 格式 | 描述 |
---|---|---|
method_idx | 單位 | 索引索引用於註解的方法的身分的method_ids 列表 |
Annotations_off | 單位 | 從文件的開頭偏移到該方法的註釋列表。偏移應為data 部分中的位置。資料的格式由下面的「 annotation_set_item 」指定。 |
參數_annotation格式
姓名 | 格式 | 描述 |
---|---|---|
method_idx | 單位 | 索引到method_ids 列表,以指定參數正在註釋的方法的身份 |
Annotations_off | 單位 | 從文件的開頭偏移到方法參數的註釋列表。偏移應為data 部分中的位置。資料的格式由下面的「 annotation_set_ref_list 」指定。 |
annotation_set_ref_list
從parameter_annotations_item引用
出現在資料部分
對齊:4個位元組
姓名 | 格式 | 描述 |
---|---|---|
尺寸 | 單位 | 清單的大小,條目 |
清單 | annotation_set_ref_item [size] | 列表的元素 |
Annotation_set_ref_item格式
姓名 | 格式 | 描述 |
---|---|---|
Annotations_off | 單位 | 如果沒有對此元素的註釋,則從檔案的開頭偏移到引用的註釋集或0 。偏移量(如果非零)應為data 部分中的位置。資料的格式由下面的「 annotation_set_item 」指定。 |
Annotation_set_item
從Annotations_directory_item,field_annotations_item,method_annotations_item和annotation_set_set_ref_item引用
出現在資料部分
對齊:4個位元組
姓名 | 格式 | 描述 |
---|---|---|
尺寸 | 單位 | 集合的大小,在條目中 |
條目 | Annotation_off_item [size] | 集合的元素。元素必須按type_idx 進行越來越多的順序排序。 |
Annotation_Off_Item格式
姓名 | 格式 | 描述 |
---|---|---|
Annotation_off | 單位 | 從文件的開頭偏移到註釋。偏移應為data 部分中的位置,並且該位置的資料格式由下面的“ annotation_item ”指定。 |
Annotation_Item
從Annotation_set_item引用
出現在資料部分
對齊:無(位元組對準)
姓名 | 格式 | 描述 |
---|---|---|
能見度 | 優位元組 | 該註釋的預期可見性(見下文) |
註解 | Encoded_annotation | 上面的「 encoded_annotation 格式」所描述的格式編碼的註解內容上面的「 encoded_value 格式」。 |
可見性值
這些是annotation_item
中visibility
欄位的選項:
姓名 | 價值 | 描述 |
---|---|---|
visibility_build | 0x00 | 僅打算在建置時間可見(例如,在其他程式碼的彙編過程中) |
visibility_runtime | 0x01 | 打算在運行時可見 |
visibility_system | 0x02 | 打算在運行時可見,但僅針對基礎系統(而不是常規用戶代碼) |
ENCODED_ARRAY_ITEM
從class_def_item引用
出現在資料部分
對齊:無(位元組對準)
姓名 | 格式 | 描述 |
---|---|---|
價值 | ENCODED_ARRAY | 代表編碼數組值的字節,以上面的“ encoded_array 編碼”下的“ encoded_value 格式”指定的格式。 |
hiddenapi_class_data_item
本節包含有關每個類別使用的限制介面的資料。
注意:隱藏的API功能是在Android 10.0中引入的,僅適用於引導類別路徑中類別的DEX檔案。以下所述的標誌清單可以在Android的未來版本中擴展。有關更多信息,請參閱非SDK介面的限制。
姓名 | 格式 | 描述 |
---|---|---|
尺寸 | 單位 | 本節的總尺寸 |
偏移量 | uint[] | class_idx 索引的偏移數組。 index class_idx 處的零數組條目意味著該class_idx 沒有數據,或所有隱藏的API標誌為零。否則,陣列條目為非零,並且包含從部分開始到此class_idx 的隱藏API標誌陣列的偏移。 |
旗幟 | uleb128 [] | 每個類別的隱藏API標誌的串聯陣列。下表中描述了可能的標誌值。標誌按與欄位相同的順序進行編碼,方法在類別資料中編碼。 |
限制標誌類型:
姓名 | 價值 | 描述 |
---|---|---|
白名單 | 0 | 可以自由使用並作為正式記錄的Android框架軟體包索引的一部分來支援的介面。 |
灰名單 | 1 | 無論應用程式的目標API等級為何,都可以使用的非SDK介面。 |
黑名單 | 2 | 無論應用程式的目標API等級為何,都無法使用的非SDK介面。存取這些介面之一會導致運行時錯誤。 |
GreyList -Max -O | 3 | 除非受到限制,否則可用於Android 8.x及以下的非SDK介面。 |
GreyList -Max -p | 4 | 除非受到限制,否則可用於Android 9.x的非SDK介面。 |
GreyList -Max -Q | 5 | 除非受到限制,否則可用於Android 10.x的非SDK介面。 |
Greylist -Max -r | 6 | 除非受到限制,否則可用於Android 11.x的非SDK介面。 |
系統註釋
系統註釋用於表示有關類別(以及方法和欄位)的各種反思性資訊。通常僅透過客戶端(非系統)代碼間接存取此資訊。
系統註解在.dex
檔案中表示為可見度設定為VISIBILITY_SYSTEM
註解。
dalvik.annotation.annotation -default
出現在註解介面中的方法上
每個註釋介面都附加了AnnotationDefault
註釋,該介面希望指示預設綁定。
姓名 | 格式 | 描述 |
---|---|---|
價值 | 註解 | 此註解的預設綁定,表示為這種類型的註解。註釋不必包括註釋定義的所有名稱;缺少名稱根本沒有預設值。 |
dalvik.annotation.closingclass
出現在課堂上
每個類別都附上一個EnclosingClass
註釋,定義為另一個類別的成員本身,或是匿名的,而不是在方法主體中定義的(例如,合成的內部類別)。每個具有此註釋的班級也必須具有InnerClass
註釋。此外,一類不得具有EnclosingClass
和EnclosingMethod
註解。
姓名 | 格式 | 描述 |
---|---|---|
價值 | 班級 | 最緊密掌握這類的課程 |
dalvik.annotation.closingMethod
出現在課堂上
每個類別在方法主體內定義的類別的EnclosingMethod
方法註釋。每個具有此註釋的班級也必須具有InnerClass
註釋。此外,一類不得具有EnclosingClass
和EnclosingMethod
註解。
姓名 | 格式 | 描述 |
---|---|---|
價值 | 方法 | 最緊密掌握這類的方法 |
dalvik.annotation.innerclass
出現在課堂上
每個類別InnerClass
註解都附加在另一類定義的詞彙範圍中定義的每個類別。具有此註釋的任何類別也必須具有EnclosingClass
註解或EnclosingMethod
註解。
姓名 | 格式 | 描述 |
---|---|---|
姓名 | 細繩 | 最初聲明的此類簡單名稱(不包括任何包裝前綴)。如果此類是匿名的,則名稱為null 。 |
AccessFlags | 整數 | 最初聲明的類別存取標誌(由於來源語言的執行模型與目標虛擬機器之間的執行模型之間的不匹配可能與有效標誌有所不同) |
dalvik.annotation.memberClasses
出現在課堂上
MemberClasses
註釋附在每個宣布會員類別的類別上。 (成員類別是具有名稱的直接內部類別。)
姓名 | 格式 | 描述 |
---|---|---|
價值 | 班級[] | 會員類的數組 |
dalvik.annotation.methodparameters
出現在方法上
注意: Android 7.1之後新增了此註解。它在早期的Android版本上的存在將被忽略。
MethodParameters
註解是可選的,可用於提供參數元數據,例如參數名稱和修飾符。
當運行時不需要參數元資料時,可以從方法或建構子中省略註解。 java.lang.reflect.Parameter.isNamePresent()
可用於檢查是否存在參數的元數據,並且相關的反射方法(例如java.lang.reflect.Parameter.getName()
將在運行時降回預設行為,如果訊息不存在。
當包含參數元資料時,編譯器必須包含產生類別(例如枚舉)的訊息,因為參數元資料包括參數是否是合成的或要求的。
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。 如果參數名稱字串為空或包含'。','','['或'/',則在運行時將拋出 java.lang.reflect.MalformedParametersException 。 |
AccessFlags | 整數[] | 相關方法的形式參數的存取標誌。數組不得為空,但如果沒有形式參數,則必須為空。 該值有點掩碼,具有以下值:
java.lang.reflect.MalformedParametersException 。 |
dalvik.annotation.Signature
出現在類,字段和方法上
Signature
註釋附加到每個類,字段或方法上,該簽名是根據type_id_item
表示的更複雜的類型定義的。 .dex
格式並未定義簽名格式;它只是為了代表源語言成功實施該語言語義所需的任何簽名。因此,簽章通常不會透過虛擬機器實作來解析(或驗證)。這些簽名只是將其移交給更高級別的API和工具(例如辯論者)。因此,任何使用簽名的用法都應寫成,以免對僅接收有效簽名做出任何假設,從而明確守護自己遇到句法無效的簽名的可能性。
因為簽名字串傾向於具有大量重複的內容,因此Signature
註釋被定義為一系列字串,其中重複的元素自然指的是相同的基礎數據,並且簽名被視為陣列中所有字串的串聯。沒有關於如何將簽名拉入單獨的字串的規則;這完全取決於生成.dex
檔案的工具。
姓名 | 格式 | 描述 |
---|---|---|
價值 | 細繩[] | 該班級或成員的簽名,作為一系列要串聯在一起的字串 |
dalvik.annotation.throws
出現在方法上
Throws
註釋附加到每個方法上,該方法被聲明為拋出一種或多種異常類型。
姓名 | 格式 | 描述 |
---|---|---|
價值 | 班級[] | 拋出的例外類型的數組 |