我们来完成一个简单的一B,没那么多学术问题的Android增量更新的实现。
对,你没看错,今天没有图!因为太简单了,什么?你不会NDK?看完了本篇你照样可以实现增量更新!
首先我们先说下原理:
用户安装的APK和新版本APK存在着diff差异,通过diff工具可以生成一个新版本与旧版本差异的文件,将新版本和旧版本的差异合并,就成了新版本的APK。(不到100字)
我先介绍下我们的小伙伴
1.bsdiff 开源工具 http://www.daemonology.net/bsdiff/bsdiff-4.3.tar.gz
2.bzip2 开源工具 http://pan.baidu.com/s/1dE4Tr2p (已经整理好!)
3.以上都是c源码! 当然我已经准备了一个在windows下编译好的exe文件(你别问我为什么只给Windows的!因为我的是Windows系统!咋的?),到时候我们需要使用这个exe文件来生成差异包
http://pan.baidu.com/s/1nvyh8N3
实现步骤:
1.将你的老版本APK与新版本的APK放在同一个目录下。
2.使用我网盘里面提供的dif工具来生成差异包
命令行走起:bsdiff.exe oldfile newfile patchfile ;老版本文件名,新版本文件名,差异文件名。对,回车之后等一会,生成了一个差异文件。
3.上NDK走起!(OK如果你对NDK一点不懂那么请继续看,如果你是神,那么请走开啦!)创建一个AndroidStudio项目,一定要勾选支持C++。
4.我们在cpp目录下来创建一个c文件,叫 native-lib.c
5.将CMakeLists.txt中的native-lib.cpp修改为native-lib.c(没记错的话应该是在21行)
5.在Activity中创建一个native方法
public native void fkDiff(String oldFile,String newFile,String patchFile);
6.在上面的方法上面按下Alt+Enter 创建ndk的方法。
7.将bzip2的源代码复制到cpp目录下。
8.将bspatch.c中的所有代码复制到 native-lib.c中的 fkDiff方法的上面(注意是上面,上面)
9.复制下面的头文件列表覆盖你的 native-lib.c中的头文件列表(不要问为什么照做就是了)
#include "bzip2/bzlib.c"
#include "bzip2/crctable.c"
#include "bzip2/compress.c"
#include "bzip2/decompress.c"
#include "bzip2/randtable.c"
#include "bzip2/blocksort.c"
#include "bzip2/huffman.c"
#include
#include
#include
#include
#include
#include
#include
10.在native-lib.c中搜索main函数,将main函数改个名字,比如我改成 fkDiffPatch
11.让我们来写几行NDK的代码在你的fkDiff函数里面
char *oldFile =(char *) (*env)->GetStringUTFChars(env, oldFile_, 0);
char *newFile = (char *)(*env)->GetStringUTFChars(env, newFile_, 0);
char *patchFile = (char *)(*env)->GetStringUTFChars(env, patchFile_, 0);
char *comm = "bspatch";
int argc = 4;
char *argv[argc];
argv[0] = comm;
argv[1] = oldFile;
argv[2] = newFile;
argv[3] = patchFile;
/**
调用我们修改过名字的函数
如果这几行代码你看不懂那么我简单说下,我们将main函数的命令行参数
传进去而已,而且我们把main函数的名字改了啊!
**/
fkDiffPatch(argc,argv);
(*env)->ReleaseStringUTFChars(env, oldFile_, oldFile);
(*env)->ReleaseStringUTFChars(env, newFile_, newFile);
(*env)->ReleaseStringUTFChars(env, patchFile_, patchFile);
12.将我们生成的差异文件,push到sdcard中。在Activity中通过一个方法来获取我们Apk的安装路径
public static String getApkFilePath(Context context, String packageName) {
try {
ApplicationInfo appInfo = context.getPackageManager()
.getApplicationInfo(packageName, 0);
return appInfo.sourceDir;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
13.在Activity中调用fkDiff的native方法
fkDiff(getApkFilePath(Context,包名),合并后存储新Apk的路径,差异文件的路径);
14.如果你能看到这里那么我还要告诉你一件事情,因为我们的diff合并是IO操作而且非常耗时,建议在线程中或者Service中去执行。
15.当合并执行完成后,调用安装Apk的代码即可(安装我们合并好的Apk啊!啥?一般人都存在了sdcard里面啊!别忘了添加sdcard的访问权限啊!)