Android開源:bsdiff - 增量更新

rkni4633 7年前發布 | 9K 次閱讀 Android開發 移動開發 C/C++

title: Android NDK之增量更新

1.增量更新使用到的庫bsdiff和bzip2

bsdiff庫是一個開源的二進制差分工具,通過對比Apk的二進制,從而進行差分包的生成。

bsdiff庫可以參考官網: bsdiff

下載地址:已經將用到的bsdiff和bzip上傳到 百度云 。

2.AS創建項目,并導入頭文件

本項目使用Android Studio,通過cmake進行編譯。

新建一個工具類,進行差分包的生成及合并

Diffutils

public class Diffutils {

static {
    System.loadLibrary("native-lib");
}


/**
 * @param oldPath 舊的安裝包路徑
 * @param newPath 新的安裝包路徑
 * @param patchPath 差分包路徑
 * @return 生成的結果
 */
public static native int generateDiffApk(String oldPath, String newPath, String patchPath);

/**
 * @param oldPath 舊的安裝包路徑
 * @param newPath 新的安裝包路徑
 * @param patchPath 差分包路徑
 * @return 生成的結果
 */
public static native int mergeDiffApk(String oldPath, String newPath, String patchPath);

}</code></pre>

導入bsdiff和bzip2的頭文件以及.c文件

將生成的.cpp文件改成.c文件。為什么要修改成.c文件?主要是因為c和c++對void * malloc這個函數編譯不同,c中不用將結果強制轉換成類型* ,而c++則不同,它必須要將結果強制轉換成類型*。我們使用到的bsdiff庫和bzip2庫好多地方都使用了malloc函數,如果使用c++編譯會報大量的錯誤,因此我們采用c編譯。

修改了cpp文件我們不要忘記在CMakeList中進行更新以及導入新的文件

CMakeList.txt

# Sets the minimum version of CMake required to build the native

library. You should either keep the default value or only pass a

value of 3.4.0 or lower.

cmake_minimum_required(VERSION 3.4.1)

Creates and names a library, sets it as either STATIC

or SHARED, and provides the relative paths to its source code.

You can define multiple libraries, and CMake builds it for you.

Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library. native-lib

         # Sets the library as a shared library.
         SHARED

         # Provides a relative path to your source file(s).
         # Associated headers in the same location as their source
         # file are automatically included.
         src/main/cpp/native-lib.c )

include src/main/cpp/include目錄下的所有文件

include_directories(src/main/cpp/include)

Searches for a specified prebuilt library and stores the path as a

variable. Because system libraries are included in the search path by

default, you only need to specify the name of the public NDK library

you want to add. CMake verifies that the library exists before

completing its build.

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 )

Specifies libraries CMake should link to your target library. You

can link multiple libraries, such as libraries you define in the

build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library. native-lib

                   # Links the target library to the log library
                   # included in the NDK.
                   ${log-lib} )</code></pre> 

3. 差分方法以及合并方法的實現

差分的方法在bsdiff.c的main函數已經實現,但是我們為了區分差分方法和合并方法我將main函數修改成generateDiffApk。同理合并方法在bspatch中已經實現,我將其main函數修改成mergeDiffApk

native-lib.c

#include <jni.h>

include "include/bsdiff.c"

include "include/bspatch.c"

JNIEXPORT jint JNICALL Java_com_nick_bsdiff_DiffutilsgenerateDiffApk(JNIEnv *env, jclass type, jstring oldPath, jstring newPath, jstring patchPath) { int argc = 4; char argv[argc]; argv[0] = (char ) "bspatch"; argv[1] = (char ) (env)->GetStringUTFChars(env, oldPath, 0); argv[2] = (char ) (env)->GetStringUTFChars(env, newPath, 0); argv[3] = (char ) (env)->GetStringUTFChars(env, patchPath_, 0);

jint result = generateDiffApk(argc, argv);

(*env)->ReleaseStringUTFChars(env, oldPath_, argv[1]);
(*env)->ReleaseStringUTFChars(env, newPath_, argv[2]);
(*env)->ReleaseStringUTFChars(env, patchPath_, argv[3]);
return result;

}

JNIEXPORT jint JNICALL Java_com_nick_bsdiff_DiffutilsmergeDiffApk(JNIEnv *env, jclass type, jstring oldPath, jstring newPath, jstring patchPath) {

int argc = 4;
char *argv[argc];
argv[0] = (char *) "bspatch";
argv[1] = (char *) (*env)->GetStringUTFChars(env, oldPath_, 0);
argv[2] = (char *) (*env)->GetStringUTFChars(env, newPath_, 0);
argv[3] = (char *) (*env)->GetStringUTFChars(env, patchPath_, 0);

printf("old apk = %s \n", argv[1]);
printf("patch = %s \n", argv[3]);
printf("new apk = %s \n", argv[2]);

jint result = mergeDiffApk(argc, argv);

(*env)->ReleaseStringUTFChars(env, oldPath_, argv[1]);
(*env)->ReleaseStringUTFChars(env, newPath_, argv[2]);
(*env)->ReleaseStringUTFChars(env, patchPath_, argv[3]);
return result;

}</code></pre>

4.效果展示

舊版本:

生成的差分包(app3.patch):

合并后的新的安裝包(app1):

安裝后:

 

來自:http://www.cnblogs.com/mc-ksuu/p/6481730.html

 

 本文由用戶 rkni4633 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!