隨著現(xiàn)在手機硬件不斷的提升,分辨率提高手機的安裝包也是越來越大了。當年NOKIA,MOTO時代,一個手機APP如果有1MB那都是算大的,2MB已經(jīng)不得了了。雖然網(wǎng)絡、存儲都已經(jīng)大大提升,但是流量還不至于廉價到APP改了一個標題要去下載一個幾兆的程序安裝包。今天就介紹安卓增量下載的實現(xiàn)。有耐心的先看原理,后面實踐!
增量升級的原理
今天我們就來實現(xiàn)類似的應用的增量升級。其實增量升級的原理很簡單,即首先將應用的舊版本Apk與新版本Apk做差分,得到更新的部分的補丁,例如舊版本的APK有5M,新版的有8M,更新的部分則可能只有3M左右(這里需要說明的是,得到的差分包大小并不是簡單的相減,因為其實需要包含一些上下文相關的東西),使用差分升級的好處顯而易見,那么你不需要下載完整的8M文件,只需要下載更新部分就可以,而更新部分可能只有3、4M,可以很大程度上減少流量的損失。
在用戶下載了差分包之后,需要在手機端將他們組合起來。可以參考的做法是先將手機端的舊版本軟件(多半在/data/下),復制到SD卡或者cache中,將它們和之前的差分patch進行組合,得到一個新版本的apk應用,如果不出意外的話,這個生成的apk和你之前做差分的apk是一致的。
增量升級的操作
在了解基本的原理之后,我們來逐步解決其中的各個難點。首先是差分包patch的生成。如果做過android手機OTA升級的同學應該注意到,在update.zip中的patch文件夾中有需要與系統(tǒng)文件同名但是以xxx.p 為后綴的文件,他們就是生成的差分patch文件。我們可以借鑒OTA系統(tǒng)升級的差分生成工具來生成我們單個應用apk的差分patch文件。OTA系統(tǒng)差分包的制作,使用命令:
./ota_from_target_files -n -i
diff_program = DIFF_PROGRAM_BY_EXT.get(ext, “bsdiff”)
至此我們就看到了android中提供我們用來制作差分增量升級包的工具,”bsdiff”,這是一個很牛X開源的二進制差分工具.相關的介紹傳送門 相關的代碼地址 或者在android的代碼目錄下 externalbsdiff bsdiff是二進制差分工具,其對應的bspatch是相應的補丁合成工具 需要注意的是增量升級的補丁包,是需要在服務器端,即PC端完成,大致流程如,制作補丁時調(diào)用bsdiff函數(shù),根據(jù)兩個不同版本的二進制文件,生成補丁文件。
命令:bsdiff oldfile newfile patchfile
例如: bsdiff xx_v1.0.apk xx_v2.0.apk xx.patch
將生成的補丁包 xx.patch放置在升級服務器上,供用戶下載升級,對應多版本需要對不同的版本進行差分,對于版本跨度較大的,建議整包升級。 用戶在下載了 xx.patch補丁包后,需要用到補丁所對應的apk,即原來系統(tǒng)安裝的舊版本apk和補丁合成的bspatch工具。系統(tǒng)舊版本的apk可以通過copy系統(tǒng)data/app目錄下的apk文件獲取,而補丁合成的bspatch可以通過將bspatch源碼稍作修改,封裝成一個so庫,供手機端調(diào)用。
bspatch的命令格式為:
bspatch oldfile newfile patchfile
和差分時的參數(shù)一樣。合成新的apk便可以用于安裝。 以上只是簡單的操作原理,增量升級還涉及很多其他方面,例如,升級補丁校驗等問題,可以參考android源碼中bootablerecoveryapplypatch的相關操作,本文只是淺析,在此不表。 不足 增量升級并非完美無缺的升級方式,至少存在以下兩點不足: 1.增量升級是以兩個應用版本之間的差異來生成補丁的,你無法保證用戶每次的及時升級到最新,所以你必須對你所發(fā)布的每一個版本都和最新的版本作差分,以便使所有版本的用戶都可以差分升級,這樣操作相對于原來的整包升級較為繁瑣,不過可以通過自動化的腳本批量生成。 2.增量升級成功的前提是,用戶手機端必須有能夠讓你拷貝出來且與你服務器用于差分的版本一致的apk,這樣就存在,例如,系統(tǒng)內(nèi)置的apk無法獲取到,無法進行增量升級;對于某些與你差分版本一致,但是內(nèi)容有過修改的(比如破解版apk),這樣也是無法進行增量升級的,為了防止合成補丁錯誤,最好在補丁合成前對舊版本的apk進行sha1sum校驗,保證基礎包的一致性。 小實驗 多說無益,實踐才是王道。下面就來簡單實踐一下,檢測之前理論的正確性。
├── bsdiff-4.3 //bsdiff的源碼路徑,官網(wǎng)獲取
│ ├── bsdiff.1
│ ├── bsdiff.c
│ ├── bspatch.1
│ ├── bspatch.c
│ └── Makefile
├── bsdiff-4.3.tar.gz
├── bsdiff4.3-win32 //windows PC端的測試工具
│ ├── Binary diff.txt
│ ├── bsdiff.exe
│ ├── bspatch.exe
│ └── LICENSE
├── bspatch //手機端的測試工具
├── oldAPK1.6.2.apk // 舊版本的apk
└── newAPK1.8.0.apk //新版本的apk
APK來做測試,在shell進入testbsdiff4.3-win32文件夾,并下運行命令:
1bsdiff.exe
oldAPK1.6.2.apk newAPK1.8.0.apk apk.patch
原來的apk(2.94M),新版本的(3.24M),得到的patch文件為1.77M,用戶需要下載的就只是1.77M,流量節(jié)省了很多。 下面先在電腦端將他們合并。
bspatch.exe oldAPK1.6.2.apk new.apk apk.patch
執(zhí)行后得到名為new.apk 的合成版本應用。這個和我們newAPK1.8.0.apk其實是一樣的。
現(xiàn)在寫一個安卓小DEMO出來,測試一下這個工具。直接在創(chuàng)建安卓工程的時候添加native支持,在CPP文件中添加以下代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205#include"com_droidupdate_jni_PatchUtil.h"#include"bzlib_private.h"#include"bzlib.h"#include#include#include#include#include#include#includestaticoff_t
offtin(u_char *buf) {off_t
y;y
= buf[7]
& 0x7F;y
= y * 256;y
+= buf[6];y
= y * 256;<code class="java plain" style="border:0px!important; padding:0px!important; bottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:base





