AI手机网,大数据营销平台,群控软件

 找回密码
 立即注册
搜索
查看: 136|回复: 2

android apk差分升级-安卓手机APK 应用 OAT升级方法

[复制链接]

464

主题

552

帖子

3347

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3347
发表于 2018-1-31 10:33:15 | 显示全部楼层 |阅读模式

差分升级主要流程就是,拿新APK和旧apk进行比较生成patch包,放在服务器上让用户下载,用户下载完成后本地apk程序再将本地的apk和patch包整合成一个最新的apk让用户进行安装。

我们需要如下2套源码来实现以上功能 bsdiff/bzlib2

这里我还要介绍一下其实android已经集成了以上两个模块,我们可以在源码的external目录里面看到bsdiff和bzip2两个文件夹对应的就是上面的2套源码。

我们在能编译的源码环境中mmm external/bsdiff看如下截图

这里out/host/linux-x86/obj32/EXECUTABLES/bspatch_intermediates/bsdiff就是用来生成patch的,out/host/linux-x86/obj32/EXECUTABLES/bspatch_intermediates/bspatch是用来整合patch生成新apk的。
所以我们可以拿bsdiff去生成patch包,然后把bspatch相关代码整合成so库加载到我们应用内去运行再生成最新的整包这整个差分升级功能就完成了。

bsdiff命令如下,大家可以自己尝试oldfile是旧包路径+文件名,newfile是新包的,patchfile是生成的patch我们这里可以随便命名为XXX.patch
./bsdiff oldfile newfile patchfile

以上前期准备完成了,现在直奔主题贴上android上功能实现需要的代码

1、新建jni目录存放so库所需源码我只写了3个文件
bs_patch.c
bs_patch.h
Android.mk

  1. #ifndef BS_PATCH_H
  2. #define BS_PATCH_H

  3. JNIEXPORT jint JNICALL Java_com_android_updatetest_util_PatchUtil_applyPatchToApk
  4.   (JNIEnv *, jclass, jstring, jstring, jstring);

  5. #endif
复制代码

bs_patch.c这个文件功能参考源码external/bsdiff/bspatch.c加了jni接口

  1. #include <jni.h>
  2. #include "bs_patch.h"
  3. #include <bzlib.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <err.h>
  8. #include <unistd.h>
  9. #include <fcntl.h>
  10. #include <sys/types.h>

  11. static off_t offtin(u_char *buf) {
  12.     off_t y;

  13.     y = buf[7] & 0x7F;
  14.     y = y * 256;
  15.     y += buf[6];
  16.     y = y * 256;
  17.     y += buf[5];
  18.     y = y * 256;
  19.     y += buf[4];
  20.     y = y * 256;
  21.     y += buf[3];
  22.     y = y * 256;
  23.     y += buf[2];
  24.     y = y * 256;
  25.     y += buf[1];
  26.     y = y * 256;
  27.     y += buf[0];

  28.     if (buf[7] & 0x80)
  29.         y = -y;

  30.     return y;
  31. }

  32. int applypatch(int argc, const char* argv[]) {
  33.     FILE * f, *cpf, *dpf, *epf;
  34.     BZFILE * cpfbz2, *dpfbz2, *epfbz2;
  35.     int cbz2err, dbz2err, ebz2err;
  36.     int fd;
  37.     ssize_t oldsize, newsize;
  38.     ssize_t bzctrllen, bzdatalen;
  39.     u_char header[32], buf[8];
  40.     u_char *oldStr, *newStr;
  41.     off_t oldpos, newpos;
  42.     off_t ctrl[3];
  43.     off_t lenread;
  44.     off_t i;

  45.     if (argc != 4)
  46.         errx(1, "usage: %s oldfile newfile patchfile\n", argv[0]);

  47.     /* Open patch file */
  48.     if ((f = fopen(argv[3], "r")) == NULL)
  49.         err(1, "fopen(%s)", argv[3]);

  50.     /*
  51.      File format:
  52.      0   8   "BSDIFF40"
  53.      8   8   X
  54.      16  8   Y
  55.      24  8   sizeof(newfile)
  56.      32  X   bzip2(control block)
  57.      32+X    Y   bzip2(diff block)
  58.      32+X+Y  ??? bzip2(extra block)
  59.      with control block a set of triples (x,y,z) meaning "add x bytes
  60.      from oldfile to x bytes from the diff block; copy y bytes from the
  61.      extra block; seek forwards in oldfile by z bytes".
  62.      */

  63.     /* Read header */
  64.     if (fread(header, 1, 32, f) < 32) {
  65.         if (feof(f))
  66.             errx(1, "Corrupt patch\n");
  67.         err(1, "fread(%s)", argv[3]);
  68.     }

  69.     /* Check for appropriate magic */
  70.     if (memcmp(header, "BSDIFF40", 8) != 0)
  71.         errx(1, "Corrupt patch\n");

  72.     /* Read lengths from header */
  73.     bzctrllen = offtin(header + 8);
  74.     bzdatalen = offtin(header + 16);
  75.     newsize = offtin(header + 24);
  76.     if ((bzctrllen < 0) || (bzdatalen < 0) || (newsize < 0))
  77.         errx(1, "Corrupt patch\n");

  78.     /* Close patch file and re-open it via libbzip2 at the right places */
  79.     if (fclose(f))
  80.         err(1, "fclose(%s)", argv[3]);
  81.     if ((cpf = fopen(argv[3], "r")) == NULL)
  82.         err(1, "fopen(%s)", argv[3]);
  83.     if (fseeko(cpf, 32, SEEK_SET))
  84.         err(1, "fseeko(%s, %lld)", argv[3], (long long) 32);
  85.     if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, NULL, 0)) == NULL)
  86.         errx(1, "BZ2_bzReadOpen, bz2err = %d", cbz2err);
  87.     if ((dpf = fopen(argv[3], "r")) == NULL)
  88.         err(1, "fopen(%s)", argv[3]);
  89.     if (fseeko(dpf, 32 + bzctrllen, SEEK_SET))
  90.         err(1, "fseeko(%s, %lld)", argv[3], (long long) (32 + bzctrllen));
  91.     if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, NULL, 0)) == NULL)
  92.         errx(1, "BZ2_bzReadOpen, bz2err = %d", dbz2err);
  93.     if ((epf = fopen(argv[3], "r")) == NULL)
  94.         err(1, "fopen(%s)", argv[3]);
  95.     if (fseeko(epf, 32 + bzctrllen + bzdatalen, SEEK_SET))
  96.         err(1, "fseeko(%s, %lld)", argv[3],
  97.                 (long long) (32 + bzctrllen + bzdatalen));
  98.     if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL)
  99.         errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err);

  100.     if (((fd = open(argv[1], O_RDONLY, 0)) < 0)
  101.             || ((oldsize = lseek(fd, 0, SEEK_END)) == -1) || ((oldStr =
  102.                     (u_char*) malloc(oldsize + 1)) == NULL)
  103.             || (lseek(fd, 0, SEEK_SET) != 0)
  104.             || (read(fd, oldStr, oldsize) != oldsize) || (close(fd) == -1))
  105.         err(1, "%s", argv[1]);
  106.     if ((newStr = (u_char*) malloc(newsize + 1)) == NULL)
  107.         err(1, NULL);

  108.     oldpos = 0;
  109.     newpos = 0;
  110.     while (newpos < newsize) {
  111.         /* Read control data */
  112.         for (i = 0; i <= 2; i++) {
  113.             lenread = BZ2_bzRead(&cbz2err, cpfbz2, buf, 8);
  114.             if ((lenread < 8)
  115.                     || ((cbz2err != BZ_OK) && (cbz2err != BZ_STREAM_END)))
  116.                 errx(1, "Corrupt patch\n");
  117.             ctrl[i] = offtin(buf);
  118.         };

  119.         /* Sanity-check */
  120.         if (newpos + ctrl[0] > newsize)
  121.             errx(1, "Corrupt patch\n");

  122.         /* Read diff string */
  123.         lenread = BZ2_bzRead(&dbz2err, dpfbz2, newStr + newpos, ctrl[0]);
  124.         if ((lenread < ctrl[0])
  125.                 || ((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END)))
  126.             errx(1, "Corrupt patch\n");

  127.         /* Add old data to diff string */
  128.         for (i = 0; i < ctrl[0]; i++)
  129.             if ((oldpos + i >= 0) && (oldpos + i < oldsize))
  130.                 newStr[newpos + i] += oldStr[oldpos + i];

  131.         /* Adjust pointers */
  132.         newpos += ctrl[0];
  133.         oldpos += ctrl[0];

  134.         /* Sanity-check */
  135.         if (newpos + ctrl[1] > newsize)
  136.             errx(1, "Corrupt patch\n");

  137.         /* Read extra string */
  138.         lenread = BZ2_bzRead(&ebz2err, epfbz2, newStr + newpos, ctrl[1]);
  139.         if ((lenread < ctrl[1])
  140.                 || ((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END)))
  141.             errx(1, "Corrupt patch\n");

  142.         /* Adjust pointers */
  143.         newpos += ctrl[1];
  144.         oldpos += ctrl[2];
  145.     };

  146.     /* Clean up the bzip2 reads */
  147.     BZ2_bzReadClose(&cbz2err, cpfbz2);
  148.     BZ2_bzReadClose(&dbz2err, dpfbz2);
  149.     BZ2_bzReadClose(&ebz2err, epfbz2);
  150.     if (fclose(cpf) || fclose(dpf) || fclose(epf))
  151.         err(1, "fclose(%s)", argv[3]);

  152.     /* Write the new file */
  153.     if (((fd = open(argv[2], O_CREAT | O_TRUNC | O_WRONLY, 0666)) < 0)
  154.             || (write(fd, newStr, newsize) != newsize) || (close(fd) == -1))
  155.         err(1, "%s", argv[2]);

  156.     free(newStr);
  157.     free(oldStr);

  158.     return 0;
  159. }

  160. jint JNICALL Java_com_android_updatetest_util_PatchUtil_applyPatchToApk(JNIEnv *env,  
  161.         jobject obj, jstring old, jstring new , jstring patch){  
  162.     int argc=4;  
  163.     char * argv[argc];  
  164.     argv[0]="bspatch";  
  165.     argv[1]=(char*)((*env)->GetStringUTFChars(env,old, 0));  
  166.     argv[2]=(char*)((*env)->GetStringUTFChars(env,new, 0));  
  167.     argv[3]=(char*)((*env)->GetStringUTFChars(env,patch, 0));  

  168.     int ret = -1;
  169.     ret = applypatch(argc, argv);  

  170.     (*env)->ReleaseStringUTFChars(env,old,argv[1]);  
  171.     (*env)->ReleaseStringUTFChars(env,new,argv[2]);  
  172.     (*env)->ReleaseStringUTFChars(env,patch,argv[3]);  
  173.     return ret;  
  174. }  
  175. 1
  176. 2
  177. 3
  178. 4
  179. 5
  180. 6
  181. 7
  182. 8
  183. 9
  184. 10
  185. 11
  186. 12
  187. 13
  188. 14
  189. 15
  190. 16
  191. 17
  192. 18
  193. 19
  194. 20
  195. 21
  196. 22
  197. 23
  198. 24
  199. 25
  200. 26
  201. 27
  202. 28
  203. 29
  204. 30
  205. 31
  206. 32
  207. 33
  208. 34
  209. 35
  210. 36
  211. 37
  212. 38
  213. 39
  214. 40
  215. 41
  216. 42
  217. 43
  218. 44
  219. 45
  220. 46
  221. 47
  222. 48
  223. 49
  224. 50
  225. 51
  226. 52
  227. 53
  228. 54
  229. 55
  230. 56
  231. 57
  232. 58
  233. 59
  234. 60
  235. 61
  236. 62
  237. 63
  238. 64
  239. 65
  240. 66
  241. 67
  242. 68
  243. 69
  244. 70
  245. 71
  246. 72
  247. 73
  248. 74
  249. 75
  250. 76
  251. 77
  252. 78
  253. 79
  254. 80
  255. 81
  256. 82
  257. 83
  258. 84
  259. 85
  260. 86
  261. 87
  262. 88
  263. 89
  264. 90
  265. 91
  266. 92
  267. 93
  268. 94
  269. 95
  270. 96
  271. 97
  272. 98
  273. 99
  274. 100
  275. 101
  276. 102
  277. 103
  278. 104
  279. 105
  280. 106
  281. 107
  282. 108
  283. 109
  284. 110
  285. 111
  286. 112
  287. 113
  288. 114
  289. 115
  290. 116
  291. 117
  292. 118
  293. 119
  294. 120
  295. 121
  296. 122
  297. 123
  298. 124
  299. 125
  300. 126
  301. 127
  302. 128
  303. 129
  304. 130
  305. 131
  306. 132
  307. 133
  308. 134
  309. 135
  310. 136
  311. 137
  312. 138
  313. 139
  314. 140
  315. 141
  316. 142
  317. 143
  318. 144
  319. 145
  320. 146
  321. 147
  322. 148
  323. 149
  324. 150
  325. 151
  326. 152
  327. 153
  328. 154
  329. 155
  330. 156
  331. 157
  332. 158
  333. 159
  334. 160
  335. 161
  336. 162
  337. 163
  338. 164
  339. 165
  340. 166
  341. 167
  342. 168
  343. 169
  344. 170
  345. 171
  346. 172
  347. 173
  348. 174
  349. 175
  350. 176
  351. 177
  352. 178
  353. 179
  354. 180
  355. 181
  356. 182
  357. 183
  358. 184
  359. 185
  360. 186
  361. 187
  362. 188
  363. 189
  364. 190
  365. 191
  366. 192
  367. 193
  368. 194
  369. 195
  370. 196
  371. 197
  372. 198
  373. 199
  374. 200
  375. 201
  376. 202
  377. Android.mk

  378. LOCAL_PATH:= $(call my-dir)
  379. include $(CLEAR_VARS)

  380. LOCAL_MODULE := libtest_bspatch

  381. LOCAL_SRC_FILES := bs_patch.c

  382. LOCAL_C_INCLUDES += external/bzip2

  383. LOCAL_STATIC_LIBRARIES := libbz

  384. include $(BUILD_SHARED_LIBRARY)
复制代码

待续






上一篇:android 安卓手机开机默认进入指定桌面或者启动器 Launcher
下一篇:MTK Android 5.0以上版本的变化-mtk芯片手机 5.0以上系统变化方案
本帖地址:http://www.aialbb.com/thread-397-1-1.html

1、专业群控,云控,脚本开发,手机ROM技术开发。开发QQ:735394006

2、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关

3、帖子作者无需承担一切因本文发表而直接或间接导致的民事或刑事法律责任

0

主题

21

帖子

22

积分

新手上路

Rank: 1

积分
22
发表于 2018-6-7 22:16:41 | 显示全部楼层
东方闪电cvcbcvbcv

10

主题

484

帖子

1018

积分

金牌会员

Rank: 6Rank: 6

积分
1018
发表于 2018-9-3 10:44:45 | 显示全部楼层

学习学习,谢谢分享………………
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|AI手机网

GMT+8, 2018-9-24 14:31 , Processed in 0.121954 second(s), 25 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表