Android動(dòng)態(tài)加載技術(shù)基礎(chǔ)之Class文件與Dex文件的結(jié)構(gòu)

Class文件

Class文件是Java虛擬機(jī)定義并被其所識(shí)別的文件格式,通俗地講窄锅,每一個(gè)接口或者類對(duì)應(yīng)一個(gè)Class文件钦勘。

Class文件格式

  • Class文件是一組以8位字節(jié)為基礎(chǔ)單位的的二進(jìn)制流。
  • 各數(shù)據(jù)項(xiàng)目之間沒有任何分隔符
  • Class文件格式采用的結(jié)構(gòu)只有兩種數(shù)據(jù)結(jié)構(gòu):無符號(hào)數(shù)和表谭企。
    • 無符號(hào)數(shù):以u(píng)1,u2等表示1倔毙,2個(gè)字節(jié)的無符號(hào)數(shù)壶栋,無符號(hào)數(shù)可用于描述數(shù)字、索引引用普监、數(shù)量值、字符串值。
    • 表:以多個(gè)無符號(hào)數(shù)或者表組成凯正,通常以_info結(jié)尾毙玻,整個(gè)Class文件就是一張表。

Class文件的組成:

Class文件結(jié)構(gòu)
  • 魔數(shù):Class文件開始四個(gè)字節(jié)是魔數(shù)廊散,用于驗(yàn)證該文件是否能被虛擬機(jī)執(zhí)行
  • 版本號(hào):魔數(shù)后四個(gè)字節(jié)則是Class文件的主版本號(hào)和次版本號(hào)
  • 常量池:版本號(hào)后面緊跟著的則是常量池部分桑滩。常量池不同與java中,它是由1開始計(jì)數(shù)的允睹,常量癡表的數(shù)目是常量個(gè)數(shù)減一运准。第0項(xiàng)為保留項(xiàng)目,用于指示當(dāng)前Class文件不需要引用任何一個(gè)常量池缭受。常量池中主要包含兩大類常量:
    • 字面量:包括文本字符串胁澳,被聲明為final的常量值等。
    • 符號(hào)引用:包括類和接口的權(quán)限定名米者,字段的名稱和描述符韭畸,方法的名稱和描述符
  • 訪問標(biāo)志:常量池部分結(jié)束后則是訪問標(biāo)志部分,該部分包括信息:是類還是接口蔓搞,是否定義為public胰丁,是否final,是否abstract等信息喂分。
  • 訪問標(biāo)志之后則是類索引锦庸,父類索引,接口索引集合部分蒲祈,該部分的主要信息為:該類的信息的索引甘萧,父類的信息的索引,實(shí)現(xiàn)接口的個(gè)數(shù)和對(duì)應(yīng)接口信息的索引讳嘱。(通過指向一個(gè)類型為CONSTANT_Class_info的類描述符常量幔嗦,從而在對(duì)應(yīng)的常量池找到相關(guān)信息)
  • 字段表:接下來的部分則是用于描述類聲明的變量信息,包括變量的作用域沥潭,是否為static邀泉,是否為final等信息。
  • 方法表:方法表則是用于描述類中方法的信息钝鸽,與字段表類似汇恤。
  • 屬性表:屬性表在字段表和方法表中都會(huì)出現(xiàn),主要用于描述某些場(chǎng)景特有的信息拔恰。比如方法是否拋出異常因谎,被final聲明的變量的值,內(nèi)部類列表等信息颜懊。

Dex文件

Dex是Android平臺(tái)上(Dalvik虛擬機(jī)财岔,art虛擬機(jī))的可執(zhí)行文件风皿,每個(gè)APK壓縮包中都包含一個(gè)(或者多個(gè)MultiDex)Dex文件,Dex文件中包含了app的所有源碼匠璧。

Dex文件的結(jié)構(gòu)

  • Dex文件是一組以8位字節(jié)為基礎(chǔ)單位的的二進(jìn)制流桐款。
  • Dex文件的各數(shù)據(jù)項(xiàng)目之間也沒有任何分隔符
  • Dex文件由文件頭,索引區(qū)夷恍,數(shù)據(jù)區(qū)三個(gè)部分組成


    Dex文件結(jié)構(gòu)
  • 其各個(gè)元素的解釋如下:
    • header:dex文件頭部魔眨,記錄整個(gè)dex文件的相關(guān)屬性
    • string_ids:字符串?dāng)?shù)據(jù)索引,記錄了每個(gè)字符串在數(shù)據(jù)區(qū)的偏移量
    • type_ids:類型數(shù)據(jù)索引酿雪,記錄了每個(gè)類型的字符串索引
    • proto_ids:原型數(shù)據(jù)索引遏暴,記錄了方法聲明的字符串,返回類型字符串指黎,參數(shù)列表
    • field_ids:字段數(shù)據(jù)索引朋凉,記錄了所屬類,類型以及方法名
    • method_ids:類方法索引袋励,記錄方法所屬類名侥啤,方法聲明以及方法名等信息
    • class_defs:類定義數(shù)據(jù)索引,記錄指定類各類信息茬故,包括接口盖灸,超類,類數(shù)據(jù)偏移量
    • data:數(shù)據(jù)區(qū)磺芭,保存了各個(gè)類的真實(shí)數(shù)據(jù)
    • link_data:連接數(shù)據(jù)區(qū)

header

文件頭記錄了dex文件的一些基本信息, 以及大致的數(shù)據(jù)分布赁炎。其各字段及解釋如下:



索引區(qū)

索引區(qū)中索引了整個(gè)dex中的字符串、類型钾腺、方法聲明徙垫、字段以及方法的信息, 其結(jié)構(gòu)體的開始位置和個(gè)數(shù)均來自dex文件頭中的記錄

  • 字符串索引區(qū):描述dex文件中所有的字符串信息
  • 類型索引區(qū):描述dex文件中所有的類型, 如類類型、基本類型放棒、返回值類型等
  • 方法聲明索引區(qū):描述dex文件中所有的方法聲明
  • 字段索引區(qū):描述dex文件中所有的字段聲明, 這個(gè)結(jié)構(gòu)中的數(shù)據(jù)全部都是索引值, 指明了字段所在的類姻报、字段的類型以及字段名稱
  • 方法索引區(qū):描述Dex文件中所有的方法, 指明了方法所在的類、方法的聲明以及方法名字

數(shù)據(jù)區(qū)

索引區(qū)中的最終數(shù)據(jù)偏移以及文件頭中描述的偏移都指向數(shù)據(jù)區(qū), 還包括了即將要解析的class_def_item

  • class_def_item:這個(gè)結(jié)構(gòu)由dex文件頭中的classDefsSize和classDefsOff所指向, 描述Dex文件中所有類定義信息, 每一個(gè)DexClassDef中包含一個(gè)DexClassData的結(jié)構(gòu)(classDataOff),每一個(gè)DexClassData中包含了一個(gè)Class的數(shù)據(jù), Class數(shù)據(jù)中包含了所有的方法, 方法中包含了該方法中的所有指令

Class文件和Dex文件對(duì)比

  • Class文件是JVM的執(zhí)行文件间螟,而Dex文件是安卓虛擬機(jī)(Dalvik吴旋,art)的執(zhí)行文件
  • Class文件對(duì)應(yīng)Java中每一個(gè)類,而Dex文件則包含整個(gè)APK文件中的JAVA代碼厢破,故Dex文件可以大大縮小體積荣瑟,減少Class文件的數(shù)據(jù)冗余,有利于在移動(dòng)端中運(yùn)行摩泪。(可以通過SDK中的dx命令將若干個(gè)Class文件轉(zhuǎn)化為Dex文件)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末笆焰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子见坑,更是在濱河造成了極大的恐慌嚷掠,老刑警劉巖捏检,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異不皆,居然都是意外死亡未檩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門粟焊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人孙蒙,你說我怎么就攤上這事项棠。” “怎么了挎峦?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵香追,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我坦胶,道長(zhǎng)透典,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任顿苇,我火速辦了婚禮峭咒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘纪岁。我一直安慰自己凑队,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布幔翰。 她就那樣靜靜地躺著漩氨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪遗增。 梳的紋絲不亂的頭發(fā)上叫惊,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音做修,去河邊找鬼霍狰。 笑死,一個(gè)胖子當(dāng)著我的面吹牛缓待,可吹牛的內(nèi)容都是我干的蚓耽。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼旋炒,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼步悠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瘫镇,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤鼎兽,失蹤者是張志新(化名)和其女友劉穎答姥,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谚咬,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鹦付,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了择卦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敲长。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖秉继,靈堂內(nèi)的尸體忽然破棺而出祈噪,到底是詐尸還是另有隱情,我是刑警寧澤尚辑,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布辑鲤,位于F島的核電站,受9級(jí)特大地震影響杠茬,放射性物質(zhì)發(fā)生泄漏月褥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一瓢喉、第九天 我趴在偏房一處隱蔽的房頂上張望宁赤。 院中可真熱鬧,春花似錦灯荧、人聲如沸礁击。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哆窿。三九已至,卻和暖如春厉斟,著一層夾襖步出監(jiān)牢的瞬間挚躯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來泰國打工擦秽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留码荔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓感挥,卻偏偏與公主長(zhǎng)得像缩搅,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子触幼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • (本文涉及的人物硼瓣、場(chǎng)景、故事情節(jié)純屬虛構(gòu),請(qǐng)勿對(duì)號(hào)入座) 巧子家的農(nóng)莊有一個(gè)雅致的名字——云廬堂鲤。 正是秋高氣爽的時(shí)...
    壇壇香閱讀 735評(píng)論 0 5
  • 能和你越來越熟而幸福??
    2e692ccbd4d6閱讀 194評(píng)論 0 0
  • (一) 43歲的奚家齊遇到了愛情亿傅,不是33歲,也不是23歲瘟栖。 當(dāng)一個(gè)男人43歲的時(shí)候葵擎,他是不敢相信自己過了人生的大...
    噔噔嗨初一閱讀 514評(píng)論 0 0
  • 休假在家,和小孩一起玩耍半哟,覺得特別有趣酬滤,可是臨近晚飯時(shí)間,寶貝越來越不乖寓涨∶粑睿總是愛鬧情緒在地上亂踢。特別易怒缅茉。 自己...
    阿霜閱讀 118評(píng)論 0 1