step1
New Project,选择 Native C++,然后一直点击 Next
生成项目代码结构如上图,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 会报错
删除如下代码
#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());
最终目录结构如下