Android NDK实现apk文件的增量更新
来源:互联网 发布:淘宝旧货二手市场 编辑:程序博客网 时间:2024/06/06 17:07
0、前言
很久没有更新博客了,这段时间总算是顺利毕业并且在实习的公司转正了,以后的目标就是多学习一些技术,争取早日成为能够独当一面的软件工程师。这篇文章计划总结一下实习期间在公司做的技术预研——Android apk文件的增量更新。相关代码的下载可以访问以下github链接:https://github.com/cundong/SmartAppUpdates,本文也是在此基础之上进行总结的。
1、原理介绍
关于增量更新,举个栗子,如果一个旧版应用有10M,一个新版应用有30M,在传统的应用更新过程中,用户必须将这30M的新版apk文件完整地从服务器下载到手机本地并安装,才能完成应用更新,但实际上更新的部分可能只占整个应用的一小部分,用户将不得不消耗极大的流量去下载与旧版apk文件相同的内容。
在增量更新的过程中,服务器会生成一个例如12M左右的差分包,用户只需要将这个差分包下载到手机本地,与旧版应用的apk文件进行合并,即可得到新版应用的apk文件,这个过程实际上就是在打补丁,比起传统的应用更新,可节约18M左右的流量,在更新时间上也能提供更好的用户体验。
2、过程分析
接下来将对增量更新的具体实现过程进行总结,主要是开源的二进制比较工具bsdiff的使用(bsdiff源码下载链接)。因为bsdiff依赖bzip2中的文件,所以项目中还需要引入bzip2的源码(bzip2源码下载链接)。在bsdiff源码中,bsdiff.c 用于生成差分包,bspatch.c 用于合成文件。2.1 差分包的生成
差分包的生成一般是在服务器端实现,每当有新版apk文件上传到服务器,过对新旧版本apk文件的比较,即可生成相对应的.patch差分包。由于相关项目的服务器是部署在Linux环境下,因此生成差分包的过程打算采用NDK编程的方式模拟实现,NDK开发环境的搭建可以参考以下链接:http://www.cnblogs.com/yejiurui/p/3476565.html首先新建一个DiffUtils类,声明native方法,用于调用底层的C函数,代码如下所示:
public class DiffUtils {/** * * @Title: genDiff * @Description: 比较新旧apk文件的差异,生成patch文件,存放于patchPath * @param oldApkPath 示例:/sdcard/old.apk * @param newApkPath 示例:/sdcard/new.apk * @param patchPath 示例:/sdcard/xx.patch * @return 0 * @throws */public static native int genDiff(String oldApkPath, String newApkPath, String patchPath);}
接下来可以将ApkPatchLibraryServer/jni目录下的文件全部复制到自己工程的jni目录下,记得把文件名和函数名修改成与自己工程相对应的名字,如下图所示:
其中com_lyq_apkaddupdate_utils_DiffUtils.c文件中的Java_com_lyq_apkaddupdatedemo_utils_DiffUtils_genDiff方法,就是在Java代码中调用的用于生成差分包的native方法,代码如下所示:
然后在jni目录下新建一个Android.mk文件,将C代码进行编译生成库文件,代码及相应注释如下所示:
#mk文件必须以定义LOCAL_PATH为开始,返回包含Android.mk的目录路径LOCAL_PATH := $(call my-dir)#负责清理LOCAL_xxx,因为所有的编译控制文件由同一个GNU Make解析和执行,#其变量是全局的,所以清理后才能避免相互影响include $(CLEAR_VARS)#生成模块的名字LOCAL_MODULE := ApkAddUpdateServer#不检查未定义的符号,用于处理undefined reference to错误LOCAL_ALLOW_UNDEFINED_SYMBOLS := true#获取$(LOCAL_PATH)目录即jni目录下的所有要编译的.c文件,并把结果放在变量MY_CPP_LIST里MY_CPP_LIST := $(wildcard $(LOCAL_PATH)/*.c)MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/bzip2/*.c)LOCAL_SRC_FILES := $(MY_CPP_LIST:$(LOCAL_PATH)/%=%)#BUILD_STATIC_LIBRARY:编译为静态库#BUILD_SHARED_LIBRARY:编译为动态库 #BUILD_EXECUTABLE:编译为Native C可执行程序include $(BUILD_SHARED_LIBRARY)保存后编译器会自动开始编译或者clean一下工程开始编译,编译成功后,即可看到libs/armeabi/目录下将生成一个.so文件,运行程序调用该文件,传入新旧版本apk文件的路径,以及.patch差分包文件的路径,即可生成.patch差分包,如下图所示:
2.2 与旧版apk的合成
合成新版apk的实现过程与差分包的生成类似。新建一个PatchUtils类,声明native方法,调用com_lyq_apkaddupdate_utils_PatchUtils.c文件中的Java_com_syd_apkaddupdateserver_utils_PatchUtils_patch方法,代码如下所示:
为了验证合成之后的apk文件是否与真正的新版apk文件相同,可以对二者进行MD5校验,如果获取到的MD5值相等,说明两份apk文件完全相同,本次增量更新成功,调用系统的应用安装程序,即可完成新版apk文件的安装。
点击下载演示Demo
- Android NDK实现apk文件的增量更新
- Android NDK实现增量更新
- Android 增量更新APK
- apk增量更新的初步实现
- 关于android apk增量更新的Demo
- NDK学习之增量更新--合并APK
- 实现android的增量更新
- android实现增量更新
- android增量更新中增量文件的生成和合并
- android增量更新中增量文件的生成和合并
- Android--增量升级--增量更新客户端的实现方法
- Android--增量升级--增量更新客户端的实现方法
- Android实现应用的增量更新\升级
- 关于android 增量更新的实现
- Android实现应用的增量更新\升级
- Android增量更新的实现(一)
- Android的增量更新
- 从ndk的安装到Android的apk增量升级(1)jni的简单应用
- 如何在GitHub上创建一个工程
- QRCode生成
- Tensorflow实战学习(三)【数据流图定义、执行、可视化】
- 课堂练习6:
- TreeSet和TreeMap初始化时有无比较器的测试
- Android NDK实现apk文件的增量更新
- 算法分析与设计课程作业第十周#1
- 网络基础知识-1
- Java中char占用几个字节
- CANoe学习笔记
- 常用 js 代码
- QRCode读取
- PAT Basic 1014
- 面向普通开发者的机器学习入门