首页 > 代码库 > 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文件提取出来,然后可以选择连文件夹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 包名.类名”,如下图:
技术分享

7.在bspatch.c中修改#include

JNIEXPORT jint JNICALL Java_com_ce_utils_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());
    }

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()方法就可以看到效果了

<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    android 客户端增量更新