Android 增量更新技术实现

APP增量更新技术实现:
增量更新整体实现思路是服务器利用新旧版本APK生成对应的差分包,客户端app检测更新后下载对应版本的差分包,在手机端合并生成新版APK然后安装从而实现版本更新,相较于传统的全量更新更加快速高效,能够为服务器节省很多带宽成本,同时为用户节省流量。进入正题:

源码可以查看:https://github.com/zhoumiqi/BsDiffUpdate,效果如下:

Android 增量更新技术实现

客户端build.gradle 引用: implementation 'com.zmq.lib.ndk:libbspatch:1.0.0'
准备工作:
1、下载bsdiff以及bzip2
下载解压bsdiff-4.3.tar.gz,得到bsdiff.c
下载解压bsdiff4.3-win32-src.zip,得到bsdiff库C++源码
官网下载不了则可以点这里http://pan.baidu.com/s/1geAwoAB下载或者自行google
下载解压bzip2-1.0.6.tar.gz,得到bzip2库C++源码(压缩算法库)
注:bsdiff库用来做差分以及合并,但是它依赖bzip2这个压缩算法库,所以需要下载这两个库的源码进行编译(生成dll或者so或者exe文件)
2、准备好Microsoft Visual Studio 、Eclipse(Tomcat)、Android Studio 3.0
注:VS用于生成服务器端所需dll动态库,Eclipse用于编写JNI以及部署运行服务器,AS用于编译生成客户端所需jar+so库以及编写Kotlin代码
3、新旧版本APK:old.apk、new.apk
注:等app编写完下载合并的代码后再打包即可
具体步骤如下:
一、服务器端根据新旧版本APK生成差分包并上传服务器
使用bsdiff(bsdiff.c)以及bzip2
1、Eclipse中新建java web 项目,定义JNI,生成头文件
a)新建一个Dynamic Web Project 命名为bsdiff_java_server
b)新建一个BsDiff类,添加一个native方法
public native static int diff(String oldFilePath, String newFilePath, String patchFilePath);

Android 增量更新技术实现
c)在命令行窗口,cd到src目录下,利用javah命令,生成com_demo_ndk_diff_server_BsDiff.h
javah命令格式:javah -d 生成.h路径 包名/类名,如果不指定路径就生成在src目录下,刷新就能看到
Android 增量更新技术实现
2、Visual Studio 编译C、C++代码生成dll动态库(导入.h以及.c文件)
a)VS中新建一个Visual C++的空项目,将bsdiff4.3-win32-src中的.h、.c、.cpp文件拷贝到项目目录下(XXX.vcxproj同级目录下即可,bspatch.cpp不用拷贝)
Android 增量更新技术实现
b)将com_demo_ndk_diff_server_BsDiff.h以及JDK目录下的jni.h,jni_md.h拷贝到项目目录
c)将头文件以及源文件添加到项目中(右键-添加-现有项)
Android 增量更新技术实现
d)将生成的头文件中的jni方法复制到bsdiff.cpp最末尾,并导入相应的头文件,编写C++具体差分方法实现代码
Android 增量更新技术实现
e)配置项目命令行以及常规-SDL检查为不检查,主要是为了解决编译运行时由于一些方法过时,警告,编码格式等产生的错误
添加命令行:-D _CRT_SECURE_NO_WARNINGS -D _CRT_NONSTDC_NO_DEPRECATE
Android 增量更新技术实现
f)生成解决方案,配置生成dll动态库以及指定方案平台
Android 增量更新技术实现

         Android 增量更新技术实现
 
Android 增量更新技术实现
3、生成差分包apk.patch,上传差分包到服务器
注:服务器端在后台页面每次上传最新版本APK时需要自动生成从最低到最新版本的所有版本对应的差分文件,并按照版本对应存储,客户端请求更新时带着自己的版本号,下载对应的差分文件,如果出现异常才考虑下载全量APK文件更新(如果部署到linux系统服务器下需要将C++代码编译成so文件使用)
a)将生成的dll文件(linux下用so库)拷贝到Eclipse项目根目录下,并在BsDiff中加载该动态库
      Android 增量更新技术实现
b)运行BsDiffTest 生成差分文件apk.patch并拷贝到WebContent目录下,部署运行服务器
      Android 增量更新技术实现
然后在浏览器中访问http://localhost:8080/bsdiff_java_server/apk.patch,如果可以正常下载apk.patch文件即为服务器运行成功,至此,服务器端完成。(app端请求时将localhost改为ip地址)
二、app端下载、合并差分包并安装合并后的新包
使用bsdiff(bspatch.c)以及bzip2
1、app启动时检查更新并下载apk.patch到指定路径下
注:需要在清单文件中添加并动态申请读写SD卡权限(demo中没有申请)
       Android 增量更新技术实现
2、AS 中建立android library项目实现JNI代码
a)创建android library bspatch_lib 配置build.gradle以及CMakeLists.txt
b)创建BsPatch 的java文件及其native方法,并生成头文件(参考服务器端)
c)在main下创建cpp目录并将bspatch.c、刚才生成的头文件以及bzip2的.c/.h文件全部拷贝进来
         Android 增量更新技术实现
d)在bspatch.c中引入生成的头文件并编写具体的合并实现代码
      Android 增量更新技术实现
3、AS中编译C、C++代码生成各平台so文件
编写好bspatch.c之后,rebuild,在build\intermediates\cmake\release\obj下就生成了各个平台对应的so库(如果只需要部分平台的so库可以在build.gradle中指定abiflter)
      Android 增量更新技术实现
4、编写app代码调用合并方法合成新版APK并安装。
在下载完差分包后便可调用BsPatch.patch方法实现合并,并在合并完成后调用扩展方法进行安装。
5、将lib项目打包为jar包供调用者集成使用【可选】
在lib的build.gradle中添加两个task,并运行相应的命令,便可得到jar
在app中直接使用jar,并添加所需要的so库,即可方便的使用libbspatch的功能。
       Android 增量更新技术实现
6、将lib项目打包发布到Maven以及Jcenter仓库,更加方便在项目中引用【可选】
具体的配置参数以及上传步骤可自行google或者参考github上的一些开源库配置即可,注意需要提前注册bintray账号(github账户亦可)。
我已经上传lib,项目中直接引用compile 'com.zmq.lib.ndk:libbspatch:1.0.0' (新版AS中compile 过时,可用implementation 替换)。
如下在build.gradle中添加即可:
implementation 'com.zmq.lib.ndk:libbspatch:1.0.0'
github地址: https://github.com/zhoumiqi/BsDiffUpdate 欢迎留言评论,并提issue,如果觉得还可以的话,记得顺手star哦!