Android的增量升级原理就是做apk版本之间的差分数据包,得到这个补丁包以后,在客户端合并旧的apk和补丁包,得到一个新的apk,最终通过新的apk实现升级。
Android的增量升级是通过jni现成的c语言bsdiff拆包和bspatch合并包。可以下载bsdiff的源码,其中bsdiff.c主要是通过一个oldApk和一个newApk,然后生成一个patch包,生成的patch包中包含标识信息,newApk的大小,差分的二进制流等信息。bspatch.c接收一个oldApk,patch,首先读取标识信息,newApk大小,生成新的newApk文件,并写入文件。写文件和读文件是调用开源库bzip2。
增量升级中动态库的生成需安装android ndk,ndk通过Android.mk文件,编译c/c++打包成so库,自动的将so和java应用打包成apk文件。
开发流程:
1、新建类PatchUpdate.java,
在类中编写native方法,并在类初始化时引入与c/c++共享库。
package com.diffpatch;
public class PatchUpdate {
static {
System.loadLibrary("update");
}
public native int patch(String oldApkPath, String newApkPath, String patchPath);
}
其中“update”就是在android.mk中定义的共享库名。
2、利用Javah生成JNI头文件,编写Android.mk
编译该项目,命令行模式,进入项目目录下的bin目录然后输入
javah -jni com.diffpatch.PatchUpdate会自动的生成
com_diffpatch_PatchUpdate.h头文件
新建jni目录,将该头文件拷贝到jni目录里,其中LOCAL_SRC_FILES要引用并实现这个头文件。将bzip2源码、bsdiff、bspatch拷贝到jni目录中,编写Android.mk,如下所示:
Android.mk文件:
#引入当前目录
LOCAL_PATH := $(call my-dir)
#调用CLEAR_VARS脚本清空变量
include $(CLEAR_VARS)
#共享库名,在java文件中引用
LOCAL_MODULE := update
LOCAL_CXXFLAGS :=
LOCAL_C_INCLUDES := $(LOCAL_PATH)
#需动态编译的c源文件
LOCAL_SRC_FILES := com_diffpatch_PatchUpdate.c
LOCAL_LDLIBS := -lz -llog
include $(BUILD_SHARED_LIBRARY)
3、做完这一步以后,使用NDK生成动态库so。命令行到工程目录,在该目录下使输入NDK_HOME\ ndk-build就会自动的在lib下生成so文件,如下图所示:
4、至此,我们可以在java程序中类PatchUpdate的patch方法做apk与补丁的合并。
备注:Demo中定义的MainActivity中使用。Demo中已经生成了so文件,不用安装NDK即可安装Demo的apk。程序中需要用的old.apk,app.patch需放在sdcard/2目录下
现有的更新方式是下载一个最新的apk包,使用现有的方法只需要下载一个最新apk与当前apk的一个差分包,然后再本地进行合并生成最新的apk包即可。
升级之前,先对本地的apk做MD5或者SHA散列,得到散列值,然后与服务器中的相应版本的apk做散列值对比,若一样,则下载patch包,否则可能是本地apk文件出问题了,需要下载完全的最新apk。