Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)

目录

 

增量更新

介绍

效果

步骤

总结


增量更新

最近换了个新手机,号称2019年的android机皇一加7plus。面对这90z的屏幕,原本不玩游戏的我也入了王者农药的坑!不过很少玩,所以基本上每次玩都要下载补丁更新才能玩。今天我们就来讲一下Android应用的增量更新。

介绍

优点:

       节省用户更新新版本的流量、时间、内存空间。

基本流程如下:

  1. app端开发人员打包新版本上传到服务器,new_version.apk
  2. 服务器通过bsdiff(依赖bzip2)两个c库,与原来纯在服务器上面的旧版本进行差分,生成补丁包patch
  3. app下载补丁包patch,与手机上安装的旧版本old_version.apk合成新的apk
  4. 安装新的apk

 

效果

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第1张图片

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第2张图片

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第3张图片

 

步骤

1、准备bsdiff和bzip2(生成补丁,合成新版本必须用到的工具)

mac/linux系统下:

下载bsdiff库:http://www.daemonology.net/bsdiff/

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第4张图片

由上图可知,bsdiff库和bspatch依赖bzip库,所以我们还要下载一个bzip库:https://sourceforge.net/projects/bzip2/

下载下来的bsdiff压缩包解压出来,进入到解压后到目录,尝试执行命令“make”,发现无法执行,报错如下:

Makefile:13: *** missing separator.  Stop.

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第5张图片

解决:

vim命令编辑MakeFile

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第6张图片

按下键盘的“i”进入编辑模式

如上图给这两行加上tab缩进,然后依次点击

键盘的“ESC”进入行末模式

输入“:wq”保存并退出vim

 

重新执行make命令,如果你出现了以下的错误,

error: unknown type name 'u_char'; did you mean 'char'?

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第7张图片

成功生成了bsdiff可执行文件,但是在生成bspathc的时候,却出现错误提示,原因是:找不到u_char的声明,所以需要引入#include 到bspatch.c文件中,再次执行make。

出现以上结果表示执行成功,在原来基础下增加了以下两个文件

 

二、引入库

配置NDK环境,不懂的可以参考我之前写的博客:https://blog.csdn.net/u014736095/article/details/90201308

配好NDK环境后,下面引入bsdiff和bspatch

1、cmakefile

2、将前面准备好的资源复制进来,有bspatch.c和bzip压缩包的解压文件

编译后会出现问题找不到bzlib.h的问题,这是因为版本的问题

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第8张图片

解决:把错误的#include 那行删除掉,让代码自动导入库即可!

已经给大家编译好,包括bsdiff,bspatch,bzip2,大家直接下载就好

https://download.csdn.net/download/u014736095/11869005

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第9张图片

2、配置Android项目ndk环境

这里不详细展开来说,提供一个比较便捷的方法,新创建一个ndk的项目,把一下重要文件复制进来即可!

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第10张图片

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第11张图片

module的build.gradle文件

//...
android {
   //...
    defaultConfig {
        //...
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }
}

 

3、引入项目bspatch.c和bzip2的库

如下图,引入bspatch.c库,用于将旧版本apk与补丁patch合成新版本apk文件。

bspatch.c所依赖的bzip2库也要复制进来。

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第12张图片

4、c库代码(至关重要)

修改CMakeLists.txt配置文件


# 设置构建本机库所需的CMake最低版本。
cmake_minimum_required(VERSION 3.4.1)

# 声明一个文件夹所有的c文件
file(GLOB bzip2_resource bzip2-1.0.6/*.c)

add_library( # 设置库的名称。
        native-lib

        #将库设置为共享库。
        SHARED

        # 提供源文件的相对路径。
        native-lib.cpp
        bspatch.c
        ${bzip2_resource}
        )

# 引入一个目录
include_directories(bzip2-1.0.6)


find_library(
        log-lib
        log )

target_link_libraries(
        native-lib
        ${log-lib} )

重新编译可能无法通过,会有异常,作以下修改即可

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第13张图片

重新编译即可。

Activity中声明一个native函数

 /**
     * 合成新的apk安装包
     * @param oldApk 旧版本
     * @param patch 补丁
     * @param newApk 新版本
     * @return
     */
    public native String increaseUpdate(String oldApk,String patch,String newApk);

编辑native-lib.cpp,声明函数与之关联,注意这个函数的命名是有规律的,Java_{类名路径,分割用“_”}_{方法名}

5、编写更新的代码

涉及到文件读写,需要配置申请权限,并兼容高版本

AndroidManifest.xml


    
    
    
    
    
        
        

            
        
    

 

file_paths.xml



    
        
    

合成新版本apk,

new AsyncTask() {
                    @Override
                    protected File doInBackground(Void... voids) {
                        createNewFile(newApkPath);
                        increaseUpdate(oldApkPath, patchPath, newApkPath);

                        return new File(newApkPath);
                    }

                    @Override
                    protected void onPostExecute(File file) {
                        super.onPostExecute(file);
                        if(file == null) return;
                        installApk(file);
                    }
                }.execute();
/**
     * 创建一个文件
     * @param path
     * @return
     */
    private File createNewFile(String path) {
        File file = new File(path);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return file;
    }

    /**
     * 安装应用
     * @param file
     */
    private void installApk(File file) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        //兼容7.0
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        } else {
            // 声明需要的临时权限
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            // 第二个参数,即第一步中配置的authorities
            String packageName = getApplication().getPackageName();
            Uri contentUri = FileProvider.getUriForFile(MainActivity.this, packageName + ".fileprovider", file);
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        }
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }

6、制作差分包

制作两个版本,必须用相同的证书,否者不成功

unix下:bsdiff/. {旧版本} {新版本} {补丁名字}

 

win下命令:bsdiff {旧版本} {新版本} {补丁名字}

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第14张图片

7、测试

标准情况下,补丁包的是在服务器上生成的,手机客户端从服务器上下载补丁patch,与手机上存在的旧版本,合成新的版本(通过调用bspatch.c中的main方法进行合成),然后安装!所以合成后,手机硬盘上会产生新的安装包。这个版本实际上与之前打包出来的新版本大小是一致的。

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第15张图片

  1. 手机上安装app_old.apk
  2. 把补丁patch复制到手机储存根目录下(模拟从服务器下载补丁)
  3. 点击“update”(增量更新)

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第16张图片Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第17张图片

 

 

注意事项:

1、mac或者Linux系统中,需要在bsdff文件夹中进行make指令编译

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第18张图片

2、bspatch.c文件记需要重新导入bzlib.h

3、正确编写CMakeList文件

4、记得调用bspatch.c中的main()方法所传进去的数组元素顺序

Android高级开发进阶之路4——增量更新(bsdiff,bspatch,bzip,ndk)_第19张图片

 

 

 

总结

实际上增量更新的核心就是两部分,

  • 会使用工具将新版本与旧版本进行差分,生成补丁包
  • 会配置项目的NDK环境,调用bspatch.c库中的代码,将下载的补丁包+旧版本合并成新版本。

 

建议先下载完整的项目下来体验一下,然后看着源码一步一步学习!否则很多坑,最好能够下载这篇文章里的库,导入你的项目,这样可以省去折腾因为版本差异导致的问题!

 

 

 

 

你可能感兴趣的:(Android开发)