Android增量更新


概述:
  •  所谓的增量更新就是一个给用户省流量更新的方案,与手机OTA升级类似,相对于热更及后台自动更不同,增量更新的方案便是让用户通过下载差异包,与原有的APK进行合并形成新的APK安装文件。举个例子:用户手机安装的APP是1.0版本,大小为20M 。而2.0的版本则为30M ,那么当用户点击更新APP的时候,仅需要从后台下载10M的差异包,然后与原有1.0版本的APK进行合并生成2.0的APK文件。
步骤解析:
  •  真实环境下:
        1、从服务器下载差异包。
        2、提取当前应用的apk文件(下方会给出方法)。
        3、将差异包与APK合并。
  •  Demo环境:
        1、本地打出差异包文件。
        2、提取当前应用的apk文件(下方会给出方法)。
        3、将差异包与APK合并。

———————————Demo环境 :————————————-

首先我们需要关注的是如何打出差异包:
  • 首先是差异包patch的生成。与安卓手机OTA升级类似,在update.zip中的patch文件夹中有需要与系统文件同名但是以xxx.p 为后缀的文件,他们就是生成的差分patch文件。我们可以借鉴OTA系统升级的差分生成工具来生成我们单个应用apk的差分patch文件。

  • 其实Android中已经为提供我们用来制作差分增量升级包的工具,”bsdiff”,(Android的代码目录下 \external\bsdiff )。这里给出已编译好的

  • bsdiff是二进制差分工具,其对应的bspatch是相应的补丁合成工具。

  • 使用差分命令:bsdiff oldfile newfile patchfile 如:./bsdiff old.apk new.apk bsdiff.patch 

  • 使用补丁合成命令:bspatch oldfile newfile patchfile 如:./bspatch old.apk new2.apk bsdiff.patch

  • 此处生成的 bsdiff.patch 便是差异包。而new2.apk 就是新合成的apk文件。

  • 我们可以使用md5命令来校验两个apk文件是否一致。md5 new.apk 及md5 new2.apk

  • 以上的操作命令都是在mac环境下操作。如果是window环境,请使用Cygwin使用方法

  • 安装注意:请在此处输入bsdiff

  • 以上就是如何生成差异包。


Android项目具体操作:
  • 首先提取APK
public class ApkExtract {
    public static String extract(Context context) {
        context = context.getApplicationContext();
        ApplicationInfo applicationInfo = context.getApplicationInfo();
        String apkPath = applicationInfo.sourceDir;
        return apkPath;
    }
}
  • 制作bspatch so

    1、 声明一个类,写个native方法

public class BsPatch {

    static {
        System.loadLibrary("bsdiff");
    }

    public static native int bspatch(String oldApk, String newApk, String patch);

}

   2、配置ndk的环境,在module的build.gradle下面添加:
   

defaultConfig {
    ndk {
        moduleName = 'bsdiff'
    }
}

   3、app/main目录下新建一个文件夹jni,把之前下载的bsdiff中的bspatch.c拷贝进去。按照jni的规则,在里面新建一个方法:
   

JNIEXPORT jint JNICALL Java_com_mrliu_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;
}

//将下放的main方法改为patchMethod方法。

   4、此时尝试运行,会提示依赖bzlib,从文件顶部的include中也能看出来
   

   5、添加依赖:
      http://www.bzip.org/downloads.html
      http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz
      
   6、将下载好的文件进行解压:
   

将其中的.h和.c文件提取出来,然后可以选择连文件夹copy到我们module的app/main/jni下,结果如下:

   7、修改bsdiff中的include
   

#include "bzip2/bzlib.h"

   8、此时运行,出现以下BUG,是main方法重复,删掉错误类的main方法即可:
   

Error:(70) multiple definition of `main'

以上便完成了jni的编写。


Android代码编写:

 将刚开始制作的old.apk安装。将bsdiff.patch放到sd卡的根目录。
 
 开启读写SDCard权限,代码中校验需要的文件是否存在
 在Activity中调用:
 

private void doBspatch() {
    final File destApk = new File(Environment.getExternalStorageDirectory(), "new2.apk");
    final File patch = new File(Environment.getExternalStorageDirectory(), "bsdiff.patch");

    //一定要检查文件都存在

    BsPatch.bspatch(ApkExtract.extract(this),
            destApk.getAbsolutePath(),
            patch.getAbsolutePath());

    if (destApk.exists())
        ApkExtract.install(this, destApk.getAbsolutePath());
    }

  通过Intent安装:
  

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);

以上便是整个增量更新的过程。


单纯的使用功能:下载so文件。在调用native之前loadLibrary。

借鉴:Android 增量更新完全解析 是增量不是热修复

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值