android 客户端增量更新

落花踏尽游何处,笑入胡姬酒肆中。这篇文章主要讲述android 客户端增量更新相关的知识,希望能为你提供帮助。
首先我们需要了解什么是增量更新, 增量更新通俗点说就是客户端只需要下载新版本与旧版本的差分包, 客户端再把差分包与旧版本进行合成得到一个新apk,在安装这个新的apk,这个新的apk其实新版本, 实现更新, 注意增量更新与热修复的区别。
原理大家可以查看: 详情请见这篇文章Android 增量更新完全解析 是增量不是热修复
我们需要了解ndk,jni,以及.so如何生成, 下面是我们windows的准备过程
1.下载bsdiff

下载地址: http://www.daemonology.net/bsdiff/bsdiff-4.3.tar.gz这里需要说明这个包中文件是做什么的: bsdiff.c和bspatch.c都是c文件, bsdiff.c是生成差分包所需要的调用的c文件, bspatch.c是差分包和旧的apk合成所需要的调用的c文件。我们下载bsdiff这个文件可以制作bsdiff和bspatch这两个工具, bsdiff这个工具是制作差分包的, bspatch这个工具是把差分包和旧的apk合成得到新apk的( 这个合成的新的apk其实就是我们服务器的新apk) 在这里我们不用制作有现成的, 这是下载windows版本中这两个文件的地址http://download.csdn.net/detail/z191726501/9651809( 在网上找到的, 博文地址为http://blog.csdn.net/z191726501/article/details/52802104) 。

2.下载bzip2这个文件
下载地址: http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz, 这个文件其实就是压缩使用的。

准备工作做完了我们就可以开始了。
首先你可以按照我的步骤开始简单的感受下效果:
1.准备两个apk,当然是用一个项目下的。一个old.apk, 一个是在旧的apk下修改代码生成新的new.apk;
2.下载上文提到的bsdiff和bspatch这两个工具的地址, 并解压;
3.把old.apk和new.apk放到bsdiff和bspatch这两个工具的目录中, 打开cmd命令行, 进入该目录;
3.cmd命令行中生成old.apk和new.apk的增量文件old-to-new.patch, 命令为“bsdiff old.apk new.apk old-to-new.patch”;
4.cmd命令行中使用增量文件old-to-new.patch和old.apk合并成新的new2.apk, 命令为“bspathc old.apk new2.apk old-to-new.patch”。, 这时候生成一个新的apk,运行这个新的apk, 是不是和我们new.apk功能是一样的
下面我们讲怎么在项目中使用:
第一: 生成.so 文件
1.配置ndk环境, 网上很多资料
2.在bzip2文件中, 将其中的.h和.c文件提取出来, 然后可以选择连文件夹(其实这个文件夹就是提取出来的只有.h和.c的文件夹)copy到我们module的app/main/jni下。
3.解压下载的bsdiff, 将其中的bspatch.c也copy到我们module的app/main/jni下。
4.在app.gradle中, defaultConfig目录下加
ndk { moduleName = ' bsdiff' }

5.建一个新类BsPatch, 注意System.loadLibrary(“bsdiff”)中的bsdiff与上一步中的moduleName中的值bsdiff一样
public class BsPatch {static { System.loadLibrary(" bsdiff" ); }public static native int bspatch(String oldApk, String newApk, String patch); }

6.生成BsPatch这个类的头文件,网上很多资料,例如在Terminal中, 切换到项目java目录下执行“javah -jni 包名.类名”,如下图:
android 客户端增量更新

文章图片

7.在bspatch.c中修改
#include < bzlib.h> 为 #include " bzip2/bzlib.h" , 并且在bspatch.c引入头文件#include " com_example_ceshi_myapplication_BsPatch_bspatch.h"

8.在bspatch.c中加如下代码, 并且把bspatch.c中的main方法改为patchMethod(只是修改名字) ,Java_com_example_ceshi_myapplication_BsPatch_bspatch这个方法就是头文件中的函数方法
JNIEXPORT jint JNICALL Java_com_example_ceshi_myapplication_BsPatch_bspatch (JNIEnv *env, jclass cls, jstring old, jstring new, jstring patch){ int argc = 4; char * argv[argc]; argv[0] = " bspatch" ; argv[1] = (char*) ((*env)-> GetStringUTFChars(env, old, 0)); argv[2] = (char*) ((*env)-> GetStringUTFChars(env, new, 0)); argv[3] = (char*) ((*env)-> GetStringUTFChars(env, patch, 0)); int ret = patchMethod(argc, argv); (*env)-> ReleaseStringUTFChars(env, old, argv[1]); (*env)-> ReleaseStringUTFChars(env, new, argv[2]); (*env)-> ReleaseStringUTFChars(env, patch, argv[3]); return ret; }

9.build中, Rebuild Project , app\\build\\intermediates\\ndk\\debug\\lib中可以看到生成的.so文件
10.我们现在就可以使用这个.so文件, 这个.so文件就是bspatch.c的.so文件, 我们在使用时一定要注意调用.so文件时的包名
**有两种方法生产.so,第一种是利用mk,第二种是利用ndk
mk编译需要写android.mk和application.mk以及在gradle中配置输出路径,如果不配置输出路径则在debug中, 但是ndk只需要在gradle中写ndk的配置, 输出在debug中**
第二步: 新建项目使用.so文件
1.注意是新建项目, 当然在上面使用的项目中也可以使用, 只不过为了区分如何生成.so和使用.so文件, 在AndroidMainfest.xml中加入权限
< uses-permission android:name= " android.permission.WRITE_EXTERNAL_STORAGE" /> < uses-permission android:name= " android.permission.READ_EXTERNAL_STORAGE" /> < uses-permission android:name= " android.permission.INTERNET" > < /uses-permission>

2.新建ApkExtract类:
public class ApkExtract { public static String extract(Context context) { context = context.getApplicationContext(); ApplicationInfo applicationInfo = context.getApplicationInfo(); String apkPath = applicationInfo.sourceDir; return apkPath; }public static void install(Context context, String apkPath) { Intent i = new Intent(Intent.ACTION_VIEW); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.setDataAndType(Uri.fromFile(new File(apkPath)), " application/vnd.android.package-archive" ); context.startActivity(i); android.os.Process.killProcess(android.os.Process.myPid()); }}

3.在MainActivity中: 调用doBspatch的方法
private void doBspatch() { final File destApk = new File(Environment.getExternalStorageDirectory(), " dest.apk" ); final File patch = new File(Environment.getExternalStorageDirectory(), " PATCH.patch" ); BsPatch.bspatch(ApkExtract.extract(this), destApk.getAbsolutePath(), patch.getAbsolutePath()); if (destApk.exists()) ApkExtract.install(this, destApk.getAbsolutePath()); }

【android 客户端增量更新】4.新建BsPatch类
public class BsPatch {static { System.loadLibrary(" bsdiff" ); }public static native int bspatch(String oldApk, String newApk, String patch); }

5.使用windows下bsdiff和bspatch的工具( http://download.csdn.net/detail/z191726501/9651809, 上文中提到的) , cmd命令行中生成old.apk和new.apk的增量文件old-to-new.patch, 命令为“bsdiff old.apk new.apk old-to-new.patch”, 得到差分包, 把差分包放到手机sd卡根目录
6.运行当前apk得到old.apk, 修改代码运行得到new.apk, 记住old.apk和新apk的效果区别, 然后手机装old.apk, 将生成的patch差分包放入手机sd卡根目录, old.apk调用doBspatch()方法就可以看到效果了

    推荐阅读