美文网首页
APP升级---BsDiff增量更新

APP升级---BsDiff增量更新

作者: 初夏的雪 | 来源:发表于2020-09-08 14:11 被阅读0次

    BsDiff算法介绍:

    bsdiff是由Conlin Percival开源的一个优秀的差分算法,而且是跨平台的。在目前很多大厂的app中都包含一个bspatch.so的库,其实主要是用于组装差分包的。感兴趣的同学可以看一下。增量更新使用的好处主要有两点:1、对用户来说,下载速度快,省流量,提高用户体验 2,对服务器来说,减少服务器的带宽压力。

    源码下载:

    https://github.com/cnSchwarzer/bsdiff-win/releases

    算法原理:

    https://www.cnblogs.com/startkey/p/10678173.html

    android使用:

    1、 native工程

       android studio新建native c++工程,新建好功能后,打开main目录,可以看到入下图所示:
    
    图 1 工程目录

    在cpp文件夹中拷贝bsdiff源码中的bzip2文件夹,并且将bsdiff.c 和bspatch.c文件也拷贝到cpp目录中,然后再CMakeLists.text中进行配置:

    cmake_minimum_required(VERSION 3.4.1)
    
    //bzip2文件夹下的文件较多是,使用目录来进行引入
    aux_source_directory(bzip2  SOURCES)
    
    add_library(
            DiffUtils   //此处是可以为您所需的library的名字
            SHARED
            native-lib.cpp
            bspatch.c     //新引入的文件
            bsdiff.c     //新引入的文件
            ${SOURCES})
    include_directories(bzip2)
    
    target_link_libraries(
            DiffUtils    //此处是可以为您所需的library的名字
            log)
    

    2、Java ,JNI,C++结构搭建

    在java目录中添加BsPatchUtils工具供java代码调用:

    public class BsPatchUtils {
        static{
            System.loadLibrary("DiffUtils");   //此处的library的名字未您在CMakeLists.text中指定的名称
        }
    
    //组装差分包
        public static native int patch(String oldApk,String newApk,String patchFile);
    
    //获取差分包
       public static native int diff(String oldApk ,String newApk,String dissFile);
    }
    

    3、功能实现

    在 BsPatchUtils工具中对应的patch ,diff静态nativie方法上使用alt+enter快捷键,生成对应的jni代码,如:cpp/native-lib.cpp所示:

    注意:
    1. 下载好bsdiff源码后,自己可以编译生成对应的exe文件,在命令行执行bsdiff命令可知,需要的参数说明:

    命令行:

     bsdiff oldfile newfile patchfile   
    
     bspatch oldfile newfile patchfile
    
    oldfile -------原文件的名称
    newfile  ------新文件的名称
    patchfile --------差分文件名
    
    上述差分和组包指令需要四个参数:指令,oldfile ,newfile ,patchfile  ,那么我们在下面的使用中就需要传递四个参数。
    
    extern "C" {
    
    //特别说明:此处的executePatch 方法是将bspatch.c中的main方法修改了一下名字,方便区分的,    executeDiff方法类似。
    extern int executePatch(int argc, char *argv[]);
    extern int executeDiff(int argc, char *argv[]);
    }
    
    /*
     * TODO  组装新包
     */
    extern "C"
    JNIEXPORT jint JNICALL
    Java_com_leon_bsdiffupdatedemo_BsPatchUtils_patch(JNIEnv *env, jclass clazz, jstring old_apk,
                                                      jstring new_apk, jstring patch_file) {
        // TODO: implement patch()
        int args = 4;
        char *argv[args];
        argv[0] = "DiffUtils";
    
        argv[1] = (char *) (env->GetStringUTFChars(old_apk, 0));
        argv[2] = (char *) (env->GetStringUTFChars(new_apk, 0));
        argv[3] = (char *) (env->GetStringUTFChars(patch_file, 0));
    
        //此处executePathch()就是上面我们修改出的
        int result = executePatch(args, argv);
    
        env->ReleaseStringUTFChars(old_apk, argv[1]);
        env->ReleaseStringUTFChars(new_apk, argv[2]);
        env->ReleaseStringUTFChars(patch_file, argv[3]);
        return result;
    }
    

    4、java使用

     public void patch() {
            File newFile = new File(getExternalFilesDir("apk"), "app.apk");
            File patchFile = new File(getExternalFilesDir("apk"), "patch.apk");
            int result = BsPatchUtils.patch(getApplicationInfo().sourceDir, newFile.getAbsolutePath(),
                    patchFile.getAbsolutePath());
            if (result == 0) {
                install(newFile);
            }
        }
    
    
    
      private void install(File file) {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 7.0+以上版本
                Uri apkUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", file);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
            } else {
                intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
            }
            startActivity(intent);
        }
    

    总之,使用差分算法对安装包进行差分包处理,这样在服务器端只提供差分包共用户下载更新,虽然更新下载速度比较快,但是每次都需要安装,这个问题作一记录。

    相关文章

      网友评论

          本文标题:APP升级---BsDiff增量更新

          本文链接:https://www.haomeiwen.com/subject/rwldektx.html