Android增量更新
来源:互联网 发布:男生用什么护肤品知乎 编辑:程序博客网 时间:2024/06/05 04:54
bspatch 官网:http://www.daemonology.net/bsdiff/
bzip2官网:http://www.bzip.org/downloads.html
下载工具包:https://github.com/zhaopingfu/DiffPatchToolsAndLinux/tree/master/tools
EclipseDemo地址:https://github.com/zhaopingfu/DnLsn11_update_server
VSDemo地址:https://github.com/zhaopingfu/DnPfDiff/tree/master/DnPfDiff
客户端Demo地址:https://github.com/zhaopingfu/DnPfLsn12Bspatch
为什么要用增量更新?
普通更新:假如一个旧包是10M,当发现有新版本之后(20M),就将20M下载下来,然后安装
增量更新:假如一个旧包是10M,当发现有新版本之后(20M),之后先生成一个差分包(以二进制的方式比较新包和旧包的差异,相同的地方记录索引,不同的地方记录索引并将内容压缩并记录) ,之后下载下来,然后和手机上已经安装的app进行合并,最后安装
比较之下发现增量更新会比普通更新更加省流量,那么有什么用呢?
如果不用360等其他app商店下载的话,一般都自己搭服务器,就按照阿里云服务器来算的话,1M流量差不多按照5毛钱来算,下载一个包节省10M,1000w的用户的话就是1000w * 10 * 0.5 ,这是一笔很大的生意啊
这里有个问题:假如我们安装完app之后就把安装包删除了,那么下载差分包之后还能合并吗?
答案当然是可以的,因为在我们第一次下载了,安装的时候,系统会帮助我们拷贝一份放在外置卡的data/app/路径下,每一个app按照自己的包名划分,一般没有root的话,这个路径下的文件是没有权限删除的,所以90%的情况下都是可以的,另外的10%是用户将手机root,获得了最高权限,然后将备份的安装包都删除了,这时候就要向服务器反馈了,将全量的包下载下来
生成差分包
步骤:
1、先生成一个windows下的差分工具
VS2013DEMO地址:https://github.com/zhaopingfu/DnPfDiff/tree/master/DnPfDiff首先下载一个bsdiff4.3-win32-src.zip解压:https://github.com/zhaopingfu/DiffPatchToolsAndLinux/tree/master/tools创建一个VS项目(这里用的是VS2013的),将平台设置为x64的在工程路径下创建两个文件夹:src include,将头文件放入include,.c和.cpp放入src里这里在源文件里找不到头文件,需要一些设置vs 找头文件 设置:右键工程 ---> 属性 ---> c++ -----> 附含包目录(头文件的目录)vs 解决 _CRT_SECURE_NO_WARNINGS:右键工程 ---> 属性 ---> c++ -----> 命令行 添加 -D _CRT_SECURE_NO_WARNINGSvs 关闭sdl 安全检查:右键工程 ---> 属性 ---> c++------>常规 ---->SDL检查 否vs 切换平台之后 需要重新配置上述依赖上面都好了之后运行项目,生成一个.exe文件在cmd中执行这个.exe PfDiff.exe appOld.apk appNew.apk apk.patch PFDiff.exe:刚才生成的.exe可执行文件 appOld.apk:旧的安装包 appNew.apk:新的安装包 apk.patch:生成的差分包执行完之后会看到在当前路径下生成了一个apk.patch差分文件
2、Eclipse中生成差分文件
在Eclipse中创建一个web工程public class DnPfDiff { public static native void diff(String oldPath, String newPath, String patchPath); static { System.loadLibrary("DnPfDiff"); }}之后进入项目的src路径下,生成头文件javah com.pf.updata.DnPfDiff
之后,将头文件放入VS项目中这里会发现在头文件中找不到jni.h,这里要找jni.h,注意是window下的JDK下面的是window下的,SDK下的是linux下的这里要在JDK里复制jni.h和jni_md.h在bsdiff.cpp中引入刚才生成的头文件,然后把main方法改个名字,改为bsdiff_main/** Class: com_pf_update_DnPfDiff* Method: diff* Signature: ()V*/JNIEXPORT void JNICALL Java_com_pf_update_DnPfDiff_diff(JNIEnv *env, jclass jcls, jstring old_path_jstr, jstring new_path_jstr, jstring patch_path_jstr){ int argc = 4; char *argv[4]; char *old_path_cstr = (char*)env->GetStringUTFChars(old_path_jstr, NULL); char *new_path_cstr = (char*)env->GetStringUTFChars(new_path_jstr, NULL); char *patch_path_cstr = (char*)env->GetStringUTFChars(patch_path_jstr, NULL); argv[0] = "bsdiff_Pf"; argv[1] = old_path_cstr; argv[2] = new_path_cstr; argv[3] = patch_path_cstr; bsdiff_main(argc, argv); env->ReleaseStringUTFChars(old_path_jstr, old_path_cstr); env->ReleaseStringUTFChars(new_path_jstr, new_path_cstr); env->ReleaseStringUTFChars(patch_path_jstr, patch_path_cstr);}之后生成一个.dll动态库,注意不是exe文件然后放入eclipse工程的根目录中eclipse里写个main方法即可执行,生成差分包public class ContantsWin { // 路径不能包含中文 public static final String BASE_PATH = "E:\\software\\Eclipse\\eclipse-jee-oxygen-R-win32-x86_64\\projects\\DnLsn11_update_server\\WebContent\\download\\"; public static final String OLD_APK_PATH = BASE_PATH + "apkOld.apk"; public static final String NEW_APK_PATH = BASE_PATH + "apkNew.apk"; public static final String PATCH_PATH = BASE_PATH + "apk.patch"; public static final String URL_PATCH_PATH = "/download/apk.patch";}public class MainTest { public static void main(String[] args) { DnPfDiff.diff(ContantsWin.OLD_APK_PATH, ContantsWin.NEW_APK_PATH, ContantsWin.PATCH_PATH); }}随便写个servlet,就可以将差分包进行下载了Eclipse下Demo地址:https://github.com/zhaopingfu/DnLsn11_update_serverVS2013DEMO地址:https://github.com/zhaopingfu/DnPfDiff/tree/master/DnPfDiff
3、Linux下生成差分文件
首先下载一个bsdiff4.3-win32-src.zip解压(最上面有链接):https://github.com/zhaopingfu/DiffPatchToolsAndLinux/tree/master/toolsbsdiff.c中的<bzlib.h>修改为"bzlib.h"除了bsdiff.c中的main方法外,其他的main方法都改成其他的名字修改权限 chmod 777 ./*生成一个可执行文件gcc -fPIC blocksort.c decompress.c bsdiff.c randtable.c bzip2.c huffman.c compress.c bzlib.c crctable.c -o PfBsDiff执行可执行文件./PfBsDiff apkOld.apk apkNew.apk apk.patch生成一个.so动态库(在服务器的后台可以直接使用,安卓客户端不能直接用,需要用NDK进行交叉编译)gcc -fPIC -shared blocksort.c decompress.c bsdiff.c randtable.c bzip2.c huffman.c compress.c bzlib.c crctable.c -o PfBsDiff.so
合并差分包(客户端完成)
客户端Demo地址:https://github.com/zhaopingfu/DnPfLsn12Bspatch
创建一个Android项目(NDK项目)首先将bzip下的头文件和源文件和bsdiff中的bspatch.c复制到cpp下(源文件里面的main方法都改名)配置CMakeLists.txt写native方法public class BsPatch { public native static int patch(String oldfile, String newfile, String patchfile); static{ System.loadLibrary("PfBisPatch"); }}生成头文件,也是上面的javah命令,cmd进入java目录,执行javah com.pf.bspatch.BsPatchbspatch中引入头文件,并实现头文件中的方法/* * Class: com_pf_bspatch_BsPatch * Method: patch * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I */JNIEXPORT jint JNICALL Java_com_pf_bspatch_BsPatch_patch (JNIEnv *env, jclass jcls, jstring old_path_jstr, jstring new_path_jstr, jstring patch_path_jstr) { int ret = -1; LOGI("jni patch begin"); char *old_path_cstr = (*env)->GetStringUTFChars(env, old_path_jstr, JNI_FALSE); char *new_path_cstr = (*env)->GetStringUTFChars(env, new_path_jstr, JNI_FALSE); char *patch_path_cstr = (*env)->GetStringUTFChars(env, patch_path_jstr, JNI_FALSE); int argc = 4; char *argv[4]; argv[0] = "PfBsPatch"; argv[1] = old_path_cstr; argv[2] = new_path_cstr; argv[3] = patch_path_cstr; //如果成功ret等于0 ret = bspatch_main(argc, argv); LOGI("jni patch end"); (*env)->ReleaseStringUTFChars(env, old_path_jstr, old_path_cstr); (*env)->ReleaseStringUTFChars(env, new_path_jstr, new_path_cstr); (*env)->ReleaseStringUTFChars(env, patch_path_jstr, patch_path_cstr); return ret;}cmd里查看下打包生成的包的MD5值和合并生成的包的MD5的值是一样的查看md5 值certutil -hashfile apkNew.apk MD53a68cc74cf9b0a3841419a54922233d1certutil -hashfile apk_new_merger.apk MD53a68cc74cf9b0a3841419a54922233d1
总结下命令
进入DnPfDiff所在路径下DnPfDiff.exe apkOld.apk apkNew.apk apk.patch DnPfDiff.exe:要执行的文件 apkOld.apk:旧的apk apkNew.apk:新的apk apk.patch:生成的差分包///////////////////////////////进入bspatch所在路径下bspatch.exe apkOld.apk apkNewMerger.apk apk.patch bspatch.exe:要执行的文件 apkOld.apk:旧的apk包 apkNewMerger.apk:合并后的文件 apk.patch:差分包//////////////////////////////////////linux下生成一个可执行文件 gcc -fPIC blocksort.c decompress.c bsdiff.c randtable.c bzip2.c huffman.c compress.c bzlib.c crctable.c -o PfBsDiff执行可执行文件 ./PfBsDiff apkOld.apk apkNew.apk apk.patch生成一个.so动态库(在服务器的后台可以直接使用,安卓客户端不能直接用,需要用NDK进行交叉编译) gcc -fPIC -shared blocksort.c decompress.c bsdiff.c randtable.c bzip2.c huffman.c compress.c bzlib.c crctable.c -o PfBsDiff.so/////////////////////////////////////////java中native方法生成头文件进入java文件所在的根目录假如是/app/src/main/java/com/pf/bspatch/BsPatch.java的话就进入到java目录下就可以了在cmd里进入java目录下,执行javah命令(配好JDK之后就可以执行) javah com.pf.bspatch.BsPatch这样就会生成一个头文件///////////////////////////////////查看md5 值 certutil -hashfile apkNew.apk MD53a68cc74cf9b0a3841419a54922233d1
- android 增量更新应用
- Android 增量更新实例
- android 增量更新
- android增量更新demo
- android实现增量更新
- android 增量更新
- Android 增量更新实例
- Android增量更新
- Android 增量更新APK
- Android APP增量更新
- Android之增量更新
- android增量更新
- Android增量更新
- android增量更新
- Android增量更新
- Android 增量更新
- Android UpdateApk 增量更新
- android 补丁包增量更新
- CentOS 7之Systemd详解之服务单元设置system.service
- 获取linux命令的源码
- redis缓存
- 高德地图Web端JavaScript API开发(一)---个性化展示(自定义地图)
- Spring Cloud Security系列教程一:入门
- Android增量更新
- tensorflow快速整体认识
- apache ab命令压力测试
- oracle中的connect by函数的使用
- 通过eclipse把spring boot项目打包成war包并部署到tomcat服务器上的步骤
- VS2015工程目录结构 + OpenCV环境配置 的最优解决方案
- linux 下安装.tar.gz文件的安装方法
- 二维码扫描与生成二维码
- 实现HTML转PDF & 多个PDF合并