原址

现在公司对于app增量更新的需求越来越多,因为增量更新不仅仅可以节省流量,更重要的一点是减少用户更新app的时间,有益于用户体验。 
  这篇文章将介绍运用patch差分包的形式实现增量更新。为了方便,就将生成差分包和合并差分包这两个过程都放在安卓机上完成。正常情况下差分包的生成是在服务端完成的。

准备工作

  1. ndk配置,使用android studio2.2及以上版本(eclipse也是可以得,这里介绍android studio)

    1)安装下图箭头标识的三个工具: 
    LLDB是一个调试工具,有了它可以在Android Studio上对native代码进行断点调试 
    CMake是个开源的跨平台自动化建构系统,它用配置文件控制建构过程(build process)的方式和Unix的Make相似,CMake配置文件取名为CMakeLists.txt 
    NDK是一个工具集,它使得开发者可以使用native代码(c、c++等等)实现app的部分功能,它提供了一份稳定的、功能有限的api头文件声明;这是进行NDK开发的核心工具,将c/c++代码编译成动态链接库so就是由它完成的(确切的说是通过NDK调用gcc来完成的)

    2)新建一个项目将include C++ support勾上即可

    3)项目创建好后会有一个CmakeLists文件(配置c/c++代码的编译选项)和cpp文件夹(c/c++代码写在这里)

  2. bsdiff和bspatch源码下载,只需要bsdiff.cbspatch.c两个c代码文件就行

  3. bzip2源码下载,因为bsdiff和bspatch都依赖bzip2。需要如下文件

以上准备完成后,将bspatch.c和bsdiff.c以及需要的bzip2的代码文件添加到项目的cpp文件夹下,再新建一个bs.h头文件,用于函数的声明,并将bspatch.c和bsdiff.c中的main函数都改名(只要名字不是main就可以),接下来就开始写代码了,其实要写的代码不多,总共不超过100行

java代码:

public class MainActivity extends AppCompatActivity {//旧版本String old =getsdpath()+"hello.apk";//新版本String newp = getsdpath()+"hehehe.apk";//差分包String patch = getsdpath()+"patch.patch";//旧版apk和差分包合并生成的新版apkString tmp = getsdpath()+"new.apk";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void click(View view){switch (view.getId()){case R.id.bt_diff:long s = System.currentTimeMillis();diff(old,newp,patch);long s1 = System.currentTimeMillis();Toast.makeText(this,"生成差分包成功,用时:"+(s1-s)+"ms",Toast.LENGTH_SHORT).show();break;case R.id.bt_patch:long s2 = System.currentTimeMillis();patch(old,tmp,patch);long s3 = System.currentTimeMillis();Toast.makeText(this,"差分包合并成功,用时:"+(s3-s2)+"ms",Toast.LENGTH_SHORT).show();break;}}private String getsdpath(){return Environment.getExternalStorageDirectory().getPath()+ File.separator;}//生成差分包public native int diff(String oldpath,String newpath,String patch);//旧apk和差分包合并public native int patch(String oldpath,String newpath,String patch);// Used to load the 'native-lib' library on application startup.static {System.loadLibrary("native-lib");}
}

重点是下面两个native函数,分别对应生成差分包和合并:

    //生成差分包public native int diff(String oldpath,String newpath,String patch);//旧apk和差分包合并public native int patch(String oldpath,String newpath,String patch);

C代码: 
bs.c:

#include "bs.h"
JNIEXPORT jint JNICALL
Java_com_example_lebronsn_bsdiffpatch_MainActivity_patch(JNIEnv *env, jobject instance, jstring oldpath_, jstring newpath_,jstring patch_) {const char* argv[4];argv[0] = "bspatch";argv[1] = (*env)->GetStringUTFChars(env,oldpath_, 0);argv[2] = (*env)->GetStringUTFChars(env,newpath_, 0);argv[3] = (*env)->GetStringUTFChars(env, patch_, 0);//该函数用于合并差分包mypatch(4,argv);(*env)->ReleaseStringUTFChars(env,oldpath_, argv[1]);(*env)->ReleaseStringUTFChars(env,newpath_, argv[2]);(*env)->ReleaseStringUTFChars(env,patch_,argv[3]);free(argv);return 0;
}JNIEXPORT jint JNICALL
Java_com_example_lebronsn_bsdiffpatch_MainActivity_diff(JNIEnv *env, jobject instance, jstring oldpath_, jstring newpath_, jstring patch_) {const char* argv[4];argv[0] = "bsdiff";argv[1] = (*env)->GetStringUTFChars(env,oldpath_, 0);argv[2] = (*env)->GetStringUTFChars(env,newpath_, 0);argv[3] = (*env)->GetStringUTFChars(env, patch_, 0);//该函数用于生成差分包mydiff(4,argv);(*env)->ReleaseStringUTFChars(env,oldpath_, argv[1]);(*env)->ReleaseStringUTFChars(env,newpath_, argv[2]);(*env)->ReleaseStringUTFChars(env,patch_,argv[3]);free(argv[0]);free(argv);return 0;
}

这段代码重点在调用的两个函数:mypatch(4,argv)mydiff(4,argv)。 
其中mypatch()bspatch中的main函数改名而来,mydiff()bsdiff中的main函数改名而来

头文件bs.h:

#ifndef BSDIFFPATCH_BS_H
#define BSDIFFPATCH_BS_H
#endif //BSDIFFPATCH_BS_H
#include <malloc.h>
#include <jni.h>
int mydiff(int argc,char *argv[]);
int mypatch(int argc,char * argv[]);
JNIEXPORT jint JNICALLJava_com_example_lebronsn_bsdiffpatch_MainActivity_patch(JNIEnv *env, jobject instance, jstring oldpath_, jstring newpath_,jstring patch_);
JNIEXPORT jint JNICALLJava_com_example_lebronsn_bsdiffpatch_MainActivity_diff(JNIEnv *env, jobject instance, jstring oldpath_, jstring newpath_, jstring patch_);

CmakeList配置:

cmake_minimum_required(VERSION 3.4.1)
add_library( native-libSHAREDsrc/main/cpp/bspatch.csrc/main/cpp/bsdiff.csrc/main/cpp/bs.csrc/main/cpp/bzip2/blocksort.csrc/main/cpp/bzip2/bzip2.csrc/main/cpp/bzip2/bzip2recover.csrc/main/cpp/bzip2/bzlib.csrc/main/cpp/bzip2/compress.csrc/main/cpp/bzip2/crctable.csrc/main/cpp/bzip2/decompress.csrc/main/cpp/bzip2/huffman.csrc/main/cpp/bzip2/randtable.c)find_library( log-liblog )target_link_libraries( native-lib${log-lib} )

到这里整个就算完成了,再贴一个cpp文件夹的内容:

我把项目代码上传了,在这里下载。 
生成差分包的时间会长一点,合并会相对来说快一点。

后记: bsdiff并不是专门为apk增量更新设计的,它可以对任何二进制文件进行差分和合并。bzip2的功能是利用哈夫曼编码对文件进行无损压缩(将差分包进行压缩便于网络传输)和解压。所以完整的流程是这样的:

  bsdiff生成patch->bzip2压缩->android下载patch->bzip2解压patch->bspatch合并patch->新的apk

Android增量更新——bsdiffbspatch相关推荐

  1. android cpp做成so库,Android增量更新(二)—制作合成文件so库

    ###前言 在上节中,我们已经学习了`Android增量更新`的实现原理,那么在Android开发的移动端,我们需要涉及到的其实是`文件合成`的这个流程. 那么,今天就来讲讲增量更新合成流程的实现吧. ...

  2. Android 增量更新实现

    如果app依赖本地更新,更新比较频繁的话,每次更新都要让用户下载完整安装包,用户体验会比较差.目前,很多应用商店都实现了apk的增量更新 正常apk更新逻辑: 打包V1.0版本,大小30M,用户安装完 ...

  3. Android增量更新框架

    Android增量更新框架 框架介绍 功能简介 简易效果图 增量更新配置 快速使用 Api详解 项目地址 框架介绍 功能简介 Android App更新框架,包含增量更新.多线程下载等功能.一句代码链 ...

  4. android中热更新模式,热更新再牛,也少不了Android 增量更新

    码个蛋(codeegg)第 785 次推文 作者: C_YQ 原文: https://juejin.im/post/5da845cdf265da5b7244c63e 码妞看世界 接骨草~ 虽然没有增量 ...

  5. Android 增量更新实例(Smart App Updates)

    http://892848153.iteye.com/blog/2022851 转自:http://my.oschina.net/liucundong/blog/160436 目录[-] 官方说明 实 ...

  6. Android 增量更新

    随着社会的发展,虽然对于一个用户而言,流量不值钱,每个用户的手机会有多少个G的流量,或者不限制流量,或者经常使用wifi.所以目前在Android端流量的优化,可能没有那么重要了.但是当我们的用户更新 ...

  7. android增量更新详细解读

    1 增量更新的意义 a 神马是增量更新? 这个概念很早就被提出,但是目前的形式,小厂用的很少,大厂用的比较多:企鹅的QQ和微信里面都有增量更新着玩意:到底神马是增量更新? 首先增量更新主要用于新版本a ...

  8. Android 增量更新完全解析 是增量不是热修复

    本文在我的微信公众号:鸿洋(hongyangAndroid)首发. 转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/5276165 ...

  9. android差分升级原理,BigNews Android 增量更新框架差分包升级 @codeKK c开源站

    支持增量包/差分包/升级包 原理:在服务器端使用 bsdiff 工具将新老安装包的差异打包为一个体积较小的差分包/升级包,然后在 App 端通过 bspatch 工具(和 bsdiff 配套的)用差分 ...

最新文章

  1. PHP生成PDF完美支持中文,解决TCPDF乱码
  2. 认知实习培训第四天总结
  3. 数据库设计与开发概述
  4. C++中log的底数理解
  5. 李开复:21世纪最需要的7种人才
  6. J2EE Architecture(1)
  7. 超越YOLOv4-tiny!YOLObile:移动设备上的实时目标检测 [左侧有码]
  8. 理解网络交换机的原理
  9. 客制化PO单据模板(实例)
  10. 安防IT化如何把握其中的共性与个性
  11. 物联网信号测试软件,物联网开关量信号采集 NPN转WIFI 检测计数器
  12. 计算机程序设计c++ 9-7:类的抽象描述举例-汽车类及圆类设计
  13. 知识分享!COB封装流程介绍!-道合顺大数据Infinigo
  14. 全国主要城市经纬度表
  15. Android学习网站(1)
  16. redhat7磁盘扩容详细步骤
  17. 详解js对称加密和非对称加密
  18. SAP smw0上传Excel模板
  19. 安卓投屏软件_【今日分享】一网打尽iOS/安卓/电脑/电视投屏软件附在线播放软件...
  20. 2021年化工自动化控制仪表考试试卷及化工自动化控制仪表复审考试

热门文章

  1. Mybatis3.3.x技术内幕(十一):执行一个Sql命令的完整流程
  2. 新东方私有化背后的秘密
  3. 学习WPF: 创建数据绑定目录树
  4. 谷歌 Daydream VR 开发工具
  5. MySQL 主键相关操作
  6. 计算机刻录光盘不显示,为什么我的CD刻录光盘的容量在
  7. mysql 更新并查询结果_数据库_基础知识_MySQL_UpdateSelect(根据查询出来的结果批量更新)...
  8. 软件测试入门到飞升上仙之web 端测试
  9. 【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 6_Logistic Regression 逻辑回归
  10. hadoop2.X集群安装与应用