Android bsdiff 增量升级

400 阅读1分钟

step1

New Project,选择 Native C++,然后一直点击 Next

image.png

image.png

生成项目代码结构如上图,cpp 目录是编写 c 和 c++ 代码的,运行项目

tip

运行时可能会报 "No toolchains found in the NDK toolchains folder for ABI with prefix: arm-linux-androideabi"

解决方法:下载 NDK,然后将 arm-linux-androideabi 放到 toolchains 目录中

step2

下载 bsdiff4.3 源码,并复制 bspatch.c 到 cpp 目录,此时 bspatch.c 会报错

image.png

删除如下代码

#include <io.h>

下载 bzip2 源码,并粘贴到 cpp 目录中,修改 CMakeLists.txt,添加如下代码,并 Sync 后报错消失

# 设置头文件查找路径
include_directories(bzip2)

继续修改 CMakeLists.txt,完整 CMakeLists.txt 代码如下

cmake_minimum_required(VERSION 3.4.1)

# 把 bzip2 目录下的原文件用 SOURCE 变量表示
aux_source_directory( # 相对目录
                      bzip2
                      # 变量名
                      SOURCE )

add_library( # 生成的so文件名,最终会生成libbspatch_utlis.so文件
             bspatch_utlis

             # Sets the library as a shared library.
             SHARED

             # 参与编译的源码.
             native-lib.cpp
             bspatch.c
             ${SOURCE} )

# 设置头文件查找路径
include_directories(bzip2)

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

target_link_libraries( # Specifies the target library.
                       bspatch_utlis

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

step3

创建 BsPatchUtils.java

package com.lixuanlin.nativeapplication;

public class BsPatchUtils {

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

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

}

patch 方法会报错,点击报错处出现红色感叹号,点击感叹号会自动生成

Java_com_lixuanlin_nativeapplication_BsPatchUtils_patch

step4

修改 native-lib.cpp 方法,同时修改 bspatch.c 的 main 方法名为 executePatch

#include <jni.h>
#include <android/log.h>

// cpp 兼容 c,正常情况下使用 extern int executePatch(int argc, char *argv[]); 即可
extern "C" {
//导入 executePatch 方法
extern int executePatch(int argc, char *argv[]);
}

extern "C"
JNIEXPORT jint JNICALL
Java_com_enjoy_dexdiff_BsPatchUtils_patch(JNIEnv *env, jclass clazz, jstring old_apk,
                                          jstring new_apk, jstring patch_file) {
    int args = 4;
    char *argv[args];
    argv[0] = "bspatch";

    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);
    //回收 String
    env->ReleaseStringUTFChars(old_apk, argv[1]);
    env->ReleaseStringUTFChars(new_apk, argv[2]);
    env->ReleaseStringUTFChars(patch_file, argv[3]);
    __android_log_print(ANDROID_LOG_ERROR,"diff","==%s==%s==%s==%d",argv[1] ,argv[2] ,argv[3],result );
    return result;
}

step5

使用 patch 方法

BsPatchUtils.patch(getApplicationInfo().sourceDir, newFile.getAbsolutePath(),
        patchFile.getAbsolutePath());

最终目录结构如下

image.png