增量更新與Dex文件簡(jiǎn)析

增量更新

概述

簡(jiǎn)單點(diǎn)來(lái)說(shuō)就是兩個(gè)文件:old和new死嗦,可通過(guò)差分工具生成它們的差分包patch,當(dāng)我們需要時(shí)粒氧,再可以通過(guò)另外一個(gè)合成工具在只有old和patch的情況下越除,恢復(fù)生成new文件。這在Android中有什么用呢外盯?它的應(yīng)用場(chǎng)景很廣泛摘盆,拿一個(gè)常見(jiàn)的場(chǎng)景來(lái)舉例,利用這個(gè)技術(shù)饱苟,可以省流量更新我們手機(jī)上已安裝的App孩擂,目前各大應(yīng)用市場(chǎng)基本都實(shí)現(xiàn)增量更新。我們安裝在手機(jī)上的App在我們的存儲(chǔ)卡上都保留有對(duì)應(yīng)的安裝包箱熬,可以理解為old文件类垦,它位于“/data/app/”文件夾下狈邑。當(dāng)我們進(jìn)行版本迭代時(shí),會(huì)上傳給應(yīng)用市場(chǎng)一個(gè)完整的安裝包蚤认,應(yīng)用市場(chǎng)會(huì)更據(jù)以前的安裝包跟最新的安裝包生成對(duì)應(yīng)的差分包對(duì)用戶進(jìn)行下發(fā)米苹,在用戶端再進(jìn)行差分包與原有版本的合成,達(dá)到省流量的目的砰琢。當(dāng)然這其中過(guò)程中還涉及到對(duì)文件完整性MD5校驗(yàn)與簽名校驗(yàn)蘸嘶,以及可能出現(xiàn)差分包比原始包更大的情況,需要采取合適的下發(fā)策略陪汽。不僅是應(yīng)用市場(chǎng)训唱,我們的應(yīng)用內(nèi)更新也可以采取相同方案。此處不再贅述掩缓。

增量更新與全量更新

  • 增量更新 就是根據(jù)歷史某一個(gè)節(jié)點(diǎn)和最新的一個(gè)節(jié)點(diǎn)雪情,對(duì)二者進(jìn)行一個(gè)差分包的生成,然后再合成的一個(gè)方案你辣。通常我們?cè)诎l(fā)布某一版本的App時(shí)巡通,前面已經(jīng)發(fā)布了很多的版本,服務(wù)端可根據(jù)最近的幾個(gè)版本分別做一下差分包進(jìn)行下發(fā)舍哄,更遠(yuǎn)的版本可不用考慮宴凉,直接給一個(gè)完整的安裝包。

  • 全量更新 可以理解為我們直接給一個(gè)完整的安裝包表悬,當(dāng)我們生成的差分包文件很大或者版本太多弥锄,差分包的管理太繁瑣時(shí),可采用全量更新策略

增量更新與熱修復(fù)

很多人對(duì)增量更新與熱修復(fù)的概念比較模糊蟆沫,這里著重強(qiáng)調(diào)一下籽暇,增量更新是在版本更新時(shí),根據(jù)差分包生成一個(gè)新的安裝包然后再安裝饭庞,會(huì)有一個(gè)安裝的過(guò)程戒悠。熱修復(fù)是用來(lái)修復(fù)bug的,比如QQ控件熱修復(fù)方案舟山,利用dx命令對(duì)某個(gè)出現(xiàn)bug的類打包成dex補(bǔ)丁包绸狐,然后再利用類加載機(jī)制,通過(guò)hook技術(shù)替換已加載的類達(dá)到修復(fù)的目的累盗,這個(gè)過(guò)程是無(wú)感知的寒矿,不會(huì)重新安裝apk,本質(zhì)上安裝在手機(jī)里的還是原來(lái)版本的apk。

常用差分若债、合成工具

網(wǎng)上有文章對(duì)BSDiff/Patch符相、HDiffPatch和XDelta三種差分包實(shí)現(xiàn)方案做對(duì)比測(cè)試,在Android APK的差分更新實(shí)現(xiàn)上拆座,XDelta差分方案實(shí)現(xiàn)是最優(yōu)的主巍。但是BSDiff/Patch 實(shí)現(xiàn)方案是最多的冠息,網(wǎng)上一大堆都是這個(gè)方案的實(shí)現(xiàn),Android系統(tǒng)也整合了這個(gè)實(shí)現(xiàn)孕索,所以這里也使用它作為實(shí)例講解怎么使用逛艰。

BSDiff

它是基于二進(jìn)制來(lái)比較兩個(gè)文件的大小,與文件格式無(wú)關(guān)搞旭,所以生成的安裝包大小也不穩(wěn)定散怖。官網(wǎng)下載網(wǎng)址為

http://www.daemonology.net/bsdiff/

下載完后可以看到如下文件

在window環(huán)境下可以通過(guò)CLion來(lái)編譯生成exe,當(dāng)然用vs也可以肄渗,喜歡的同學(xué)可以自己去探究

bsdiff

bsdiff是用來(lái)生成差分包的镇眷,可以通過(guò)如下命令來(lái)生成

C:\Users\XXX\Desktop\bsdiff>bsdiff old.apk new.apk patch.apk

介紹下上面命令的用法:

bsdiff:固定寫(xiě)法

old.apk:舊文件名稱

new.apk: 新文件名稱

patch.apk :生成的差分包名稱,可隨便取名

最終生成

old翎嫡、new是我們的歷史版本與最新版本欠动,patch.apk就是我們生成的目標(biāo)文件

bspatch

下面介紹下,我們Android端怎么使用bspatch來(lái)合成我們的安裝包惑申,上面演示的是在windows環(huán)境下生成差分包具伍,但我們Android是基于linux的,自然不能使用exe文件圈驼,我們得把源碼拿過(guò)來(lái)在我們的App內(nèi)生成so庫(kù)再使用人芽。關(guān)于NDK基礎(chǔ)部分我們略過(guò)。

1.新建c/c++工程绩脆,并把源碼拷貝過(guò)來(lái)萤厅,配置好cmake文件

2.編寫(xiě)native方法

 



其中圖中的executePatch方法為源文件中的main方法,只是這里為了方便辨識(shí)靴迫,給改了個(gè)名字而已

3.合成差分包并安裝

最終在activity中調(diào)用patch方法即可進(jìn)行安裝包的合成


patch包在這里由手動(dòng)放在data/data/packagename/cache/目錄下的來(lái)模擬從服務(wù)器請(qǐng)求的情況惕味,app.apk即為我們生成的目標(biāo)文件,通過(guò)安裝它來(lái)更新App

demo源碼鏈接如下:

https://github.com/xuchengpu/BSPatch.git

Dex文件簡(jiǎn)析

Dex文件是Android系統(tǒng)的可執(zhí)行文件玉锌,包含應(yīng)用程序的全部操du作指令以及運(yùn)行時(shí)數(shù)據(jù)赦拘。 當(dāng)java程序編譯成class后,還需要使用dx工具將所有的class文件整合到一個(gè)dex文件芬沉,目的是其中各個(gè)類能夠共享 數(shù)據(jù),在一定程度上降低了冗余阁猜,同時(shí)也使文件結(jié)構(gòu)更加緊湊丸逸,實(shí)驗(yàn)表明,dex文件是傳統(tǒng)jar文件大小的50%左 右剃袍。dex 文件可以分為3個(gè)模塊黄刚,頭文件、索引區(qū)民效、數(shù)據(jù)區(qū)憔维。頭文件概況的描述了整個(gè) dex 文件的分布涛救,包括每一個(gè)索 引區(qū)的大小跟偏移。索引區(qū)表示每個(gè)數(shù)據(jù)的標(biāo)識(shí)业扒,索引區(qū)主要是指向數(shù)據(jù)區(qū)的偏移检吆。

從圖中可以看出,像String_ids程储、Type_ids等這些每個(gè)文件共有的信息蹭沛,都被整合到一起,減少文件體積大小章鲤。

我們可以使用010Editor查看工具打開(kāi)一個(gè)dex來(lái)同步分析摊灭。

image-20200908110318953

Header

是dex文件的頭部,記錄整個(gè)dex文件的相關(guān)屬性败徊,長(zhǎng)度為112個(gè)字節(jié)帚呼。

頭文件里包含以下部分:

magic(魔數(shù)):每個(gè)文件的頭文件里前8個(gè)字節(jié),代表文件的格式

checksum: 文件校驗(yàn)碼皱蹦,使用 alder32 算法校驗(yàn)文件除去 maigc煤杀、checksum 外余下的所有文件區(qū)域,用于 檢 查文件錯(cuò)誤根欧。 signature: 使用 SHA-1 算法 hash 除去 magic怜珍、checksum 和 signature 外余下的所有文件區(qū)域, 用于唯一 識(shí)別本文件 凤粗。 file_size: dex 文件大小 header_size: header 區(qū)域的大小酥泛,固定為 0x70 endian_tag: 大小端標(biāo)簽,dex 文件格式為小端嫌拣,固定值為 0x12345678 map_off: map_item 的偏移地址柔袁,該 item 屬于 data 區(qū)里的內(nèi)容,值要大于等于 data_off 的大小异逐,處于 dex 文件的末端捶索。

其他 xx_off , xx_size 成對(duì)出現(xiàn)灰瞻,表示數(shù)據(jù)的偏移與數(shù)據(jù)個(gè)數(shù)腥例。

這里以16進(jìn)制方式來(lái)查看magic為例:

這幾個(gè)數(shù)值轉(zhuǎn)換為字符串為dex.035,被稱為文件簽名。dex代表文件格式酝润,035代表版本號(hào)燎竖。

索引區(qū)

StringIds : 描述了 dex 文件中所有的字符串。記錄的數(shù)據(jù)只有一個(gè)偏移量要销,偏移量指向了 數(shù)據(jù)區(qū)Data中 的一 個(gè)字符串

type_ids : 類似數(shù)據(jù)索引构回,記錄了每個(gè)類型的字符串索引

proto_ids : 原型數(shù)據(jù)索引,記錄了方法聲明的字符串,返回類型字符串纤掸,參數(shù)列表

field_ids : 字段數(shù)據(jù)索引脐供,記錄了所屬類,類型以及方法名

method_ids :類方法索引借跪,記錄方法所屬類名政己,方法聲明以及方法名等信息

class_defs :類定義數(shù)據(jù)索引,記錄指定類各類信息垦梆,包括接口匹颤,超類,類數(shù)據(jù)偏移量

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

保存了各個(gè)類的真實(shí)數(shù)據(jù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末托猩,一起剝皮案震驚了整個(gè)濱河市印蓖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌京腥,老刑警劉巖赦肃,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異公浪,居然都是意外死亡他宛,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門欠气,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)厅各,“玉大人,你說(shuō)我怎么就攤上這事预柒《犹粒” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵宜鸯,是天一觀的道長(zhǎng)憔古。 經(jīng)常有香客問(wèn)我,道長(zhǎng)淋袖,這世上最難降的妖魔是什么鸿市? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮即碗,結(jié)果婚禮上焰情,老公的妹妹穿的比我還像新娘。我一直安慰自己剥懒,他們只是感情好烙样,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蕊肥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上壁却,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天批狱,我揣著相機(jī)與錄音,去河邊找鬼展东。 笑死赔硫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的盐肃。 我是一名探鬼主播爪膊,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼砸王!你這毒婦竟也來(lái)了推盛?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤谦铃,失蹤者是張志新(化名)和其女友劉穎耘成,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體驹闰,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瘪菌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嘹朗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片师妙。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖屹培,靈堂內(nèi)的尸體忽然破棺而出默穴,到底是詐尸還是另有隱情,我是刑警寧澤惫谤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布壁顶,位于F島的核電站,受9級(jí)特大地震影響溜歪,放射性物質(zhì)發(fā)生泄漏若专。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一蝴猪、第九天 我趴在偏房一處隱蔽的房頂上張望调衰。 院中可真熱鬧,春花似錦自阱、人聲如沸嚎莉。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)趋箩。三九已至赃额,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間叫确,已是汗流浹背跳芳。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留竹勉,地道東北人飞盆。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像次乓,于是被迫代替她去往敵國(guó)和親吓歇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359