首先我们需要了解什么是增量更新,增量更新通俗点说就是客户端只需要下载新版本与旧版本的差分包,客户端再把差分包与旧版本进行合成得到一个新 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 文件提取出来,然后可以选择连文件夹 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 classBsPatch {static{
- System.loadLibrary("bsdiff");
- }public staticnativeint bspatch(String oldApk, String newApk, String patch);
- }
6. 生成 BsPatch 这个类的头文件, 网上很多资料, 例如在 Terminal 中,切换到项目 java 目录下执行 "javah -jni 包名. 类名", 如下图:
7. 在 bspatch.c 中修改 #include
- JNIEXPORT jint JNICALL Java_com_ce_utils_BsPatch_bspatch
- (JNIEnv *env, jclass cls,
- jstring old, jstringnew, 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]);returnret;
- }
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 classApkExtract {public staticStringextract(Context context) {
- context = context.getApplicationContext();
- ApplicationInfo applicationInfo = context.getApplicationInfo();
- String apkPath = applicationInfo.sourceDir;returnapkPath;
- }public static void install(Context context, String apkPath) {
- Intent i =newIntent(Intent.ACTION_VIEW);
- i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- i.setDataAndType(Uri.fromFile(newFile(apkPath)),"application/vnd.android.package-archive");
- context.startActivity(i);
- android.os.Process.killProcess(android.os.Process.myPid());
- }
- }
3. 在 MainActivity 中:调用 doBspatch 的方法
- private void doBspatch() {finalFile destApk =newFile(Environment.getExternalStorageDirectory(),"dest.apk");finalFile patch =newFile(Environment.getExternalStorageDirectory(),"PATCH.patch");
- BsPatch.bspatch(ApkExtract.extract(this),
- destApk.getAbsolutePath(),
- patch.getAbsolutePath());if(destApk.exists())
- ApkExtract.install(this, destApk.getAbsolutePath());
- }
4. 新建 BsPatch 类
- public classBsPatch {static{
- System.loadLibrary("bsdiff");
- }public staticnativeint 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() 方法就可以看到效果了
来源: http://blog.csdn.net/flowermachao/article/details/70547749