ndk11_增量更新,哈夫曼算法在windows,linux服务器和安卓客户端的使用

一、增量更新原理

  • 2.普通更新流程图


  • 3.增量更新流程图


  • 4.哈夫曼算法
  • 5.热修复、插件化和增量更新的区别

二、生成windows环境的差分工具

  • 1.下载Windows环境的源码
  • 2.创建VS工程

    为了方便管理在自己的VS工程里面创建include 和 src 两个文件夹

    将头文件放入include 源文件放入src

  • 3.关联头文件
  • 4.关联源文件
  • 5.配置VS头文件路径(引入include目录)
  • 6.VS解决 _CRT_SECURE_NO_WARNINGS 警告

    右键工程 ---> 属性 ---> c++ -----> 命令行 添加 -D _CRT_SECURE_NO_WARNINGS

  • 7.关闭sdl 安全检查

      error C4996: 'setmode': The POSIX name for this item is deprecated.
       Instead, use the ISO C++ conformant name: _setmode. See online help for 
      details.    d:\develop\visual_studio\workspacec++\hubindiffdemo\hubindiffdemo\src\bzlib.c   1422    1   hubinDiffDemo
    
  • 8.运行成功后生成了差分工具 hubinDiff.exe 位于Debug目录下(也可以配置生成hubinDiff.dll动态库,切换平台后需要重新设置以上步骤)

      cd到差分工具所在路径下为apk生成差分包
      
      hubinDiff.exe appOld.apk appNew.apk  app.patch
    

三、windows服务器jni动态生成差分包

  • 1.定义native方法

      /*
       *oldPath  :旧版本apk路径
       *newPath  :新版本apk路径
       *patchPath:差分包生成路径
       **/
      public static native void diff(string oldPath,String newPath,String patchPath);
    
  • 2.JNI层调用差分算法

    //将第bsdiff.cpp源文件228行main()入口函数:int main(int argc,char *argv[]) 
    //更名为int bsdiff_main(int argc,char *argv[])
    
    JNIEXPORT void JNICALL Java_hubin_diff
    (JNIEnv *env, jclass jazz,jstring oldPath_jst, jstring newPath_jst, jstring patchPath_jst)
    {
        int argc = 4;
        char *argv[4];
    
        char *oldPath = (char*)env->GetStringUTFChars(oldPath_jst, NULL);
        char *newpath = (char*)env->GetStringUTFChars(newPath_jst, NULL);
        char *patchPath = (char*)env->GetStringUTFChars(patchPath_jst, NULL);
        argv[0] = "bsdiff_Tim";
        argv[1] = oldPath;
        argv[2] = newpath;
        argv[3] = patchPath;
    
        bsdiff_main(argc,argv); //调用差分算法
    
        env->ReleaseStringUTFChars(oldPath_jst, oldPath);
        env->ReleaseStringUTFChars(newPath_jst, newpath);
        env->ReleaseStringUTFChars(patchPath_jst, patchPath);
    
    }

四、生成Linux环境的差分工具

  • 1.在官网下载Linux平台的bspatch源码

  • 2.拷贝bsdiff里面的源文件和bzip2里面的.c和.h源文件

  • 3.将bsdiff.c的源文件中的 #include <bzlib.h> 改成 #include "bzlib.h"
  • 4.将除了bsdiff.c的其他源文件中的main方法改成其它名字

  • 5.将所有源文件传输到linux服务器的文件夹下(/home/Bsdiff)

  • 6.cd到Bsdiff文件夹下修改其权限为全部可执行 命令:chmod 777 ./*

  • 7.使用gcc编译生成hubinBsDiff, 下面命令行中“...”表示其它所有的源文件

      gcc fPIC blocksort.c decompress.c bsdiff.c  randtable.c  bzip2.c huffman.c compress.c bzlib.c crctable.c -o hubinBsDiff   
    
  • 8.使用hubinBsDiff生成差分包

      hubinBsDiff appOld.apk appNew.apk  app.patch
    
  • 9.补充:如果需要生成so库,需要引入jni头文件,已经用javah生存的头文件并使用如下命令:

      gcc -I/usr/local/jdk/jdk1.8.0_152/include/linux -I/usr/local/jdk/jdk1.8.0_152/include -fPIC blocksort.c decompress.c bsdiff.c  randtable.c  bzip2.c huffman.c compress.c bzlib.c crctable.c  -shared -o libhubiniBsDiff.so
    
      备注:-I/usr/local/jdk/jdk1.8.0_152/include/linux 和 -I/usr/local/jdk/jdk1.8.0_152/include表示jni头文件所在的路径
    

五、android平台合并

  • 1.同上步骤,拷贝所有linux版本源码至工程的cpp目录下重命名所有源文件中的main方法,引入正确的头文件路径,
  • 2.配置CmakeList

      cmake_minimum_required(VERSION 3.4.1)
      
      file(GLOB my_c_path src/main/cpp/bzip2/*.c)
      add_library( TimBisPatch
                   SHARED
      
                   ${my_c_path}  #添加bzip2目录下的所有源文件
                   src/main/cpp/bspatch.c)
      
      find_library(  log-lib
                    log )
      
      target_link_libraries(TimBisPatch
      
                             ${log-lib} )
    
  • 3.java层native方法

      public native static int patch(String oldfile, String newFile, String patchFile);
    
  • 4.JNI层调用bspatch.c中改名后的main方法

    JNIEXPORT jint JNICALL Java_hubin_BsPatch_patch
            (JNIEnv *env, jclass jazz, jstring oldPath_jstr, jstring newPath_jstr, jstring patchPatch_jst) {
    
        int ret= -1;
        LOGD(" jni patch begin");
    
        char *oldPath = (*env) -> GetStringUTFChars(env, oldPath_jstr, JNI_FALSE);
        char *newPath = (*env) -> GetStringUTFChars(env, newPath_jstr, JNI_FALSE);
        char *patchPath = (*env) -> GetStringUTFChars(env, patchPatch_jst, JNI_FALSE);
    
        int argc = 4;
        char *argv[4];
    
        argv[0] = "hubinBsPatch"; //随便定义一个名字
        argv[1] = oldPath;   //老版本apk路径
        argv[2] = newPath;  //新版本apk路径
        argv[3] = patchPath;  //差分包所在路径
    
        //如果成功ret等于0
        ret = bspatch_main(argc,argv); //调用合并算法

        (*env) -> ReleaseStringUTFChars(env, oldPath_jstr, oldPath);
        (*env) -> ReleaseStringUTFChars(env, newPath_jstr, newPath);
        (*env) -> ReleaseStringUTFChars(env, patchPatch_jst, patchPath);
        return ret;
    
    }
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.ApplicationInfo;
    import android.content.pm.PackageInfo;
    import android.content.pm.PackageManager;
    import android.net.Uri;
    import android.text.TextUtils;
    import android.util.Log;

    public class ApkUtils {
        //获取APK版本号 根据 key uuid判断(渠道 版本)
        public static int getVersionCode (Context context, String packageName) {
            PackageManager pm = context.getPackageManager();
            try {
                PackageInfo info = pm.getPackageInfo(packageName, 0);
                Log.d("Tim","getVersionCode = "+info.versionCode);
                return info.versionCode;
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
                return 0;
            }
        }
    
        /**
         * 获取已安装Apk文件的源Apk文件
         * 如:/data/app/my.apk
         *
         * @param context
         * @param packageName
         * @return
         */
        public static String getSourceApkPath(Context context, String packageName) {
            if (TextUtils.isEmpty(packageName))
                return null;
    
            try {
                ApplicationInfo appInfo = context.getPackageManager()
                        .getApplicationInfo(packageName, 0);
                return appInfo.sourceDir;
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
            return null;
        }
    
    
    
        /**
         * 安装Apk
         *
         * @param context
         * @param apkPath
         */
        public static void installApk(Context context, String apkPath) {
    
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.parse("file://" + apkPath),
                    "application/vnd.android.package-archive");
    
            context.startActivity(intent);
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 增量更新在Android开发中是一种很常见的技术。 增量更新的原理 增量更新的原理非常简单,就是将本地apk与服务...
    re冷星阅读 1,559评论 3 3
  • 版权声明:本文为LooperJing原创文章,转载请注明出处! 前言 如果要对一个 APP 进行更新,你会怎么做呢...
    LooperJing阅读 3,458评论 0 28
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • 最近就是在练习ndk开发,刚好遇到android增量更新的话题,主要是工具的运用,略带使用第三方so库的流程~~~...
    红黑军团号阅读 547评论 1 3
  • @[增量更新,差分包,bsdiff/patch] 背景 随着Android app的不断迭代升级,功能越来越多,a...
    SunYo阅读 14,371评论 2 7