感覺還是有必要記一下。容易忘記的人。
增量更新不同于熱修復(fù),從字面意思就知道,他是在原有apk的基礎(chǔ)上做一個增加的。常用于版本的迭代,他可以大大節(jié)省用戶的流量。
and.....。
增量更新關(guān)鍵在于生成補(bǔ)丁包。(最難的這個已經(jīng)有工具替我們實(shí)現(xiàn)了),然后就是將原來的apk和補(bǔ)丁包合成生成新的apk。
windows 系統(tǒng)下要獲取bsdiff.exe 和bspatch.exe 還是比較麻煩的。(我是網(wǎng)上直接拿了兩個已經(jīng)生成好的可執(zhí)行文件),當(dāng)然生成補(bǔ)丁包還是放在服務(wù)端的,客戶端要做的就是將服務(wù)端的補(bǔ)丁包下載下來,然后合成新的apk。
--------------------------------------------------分割----------------------------------------------------------
我這邊就簡單記入如何生成用于合成補(bǔ)丁的so 庫。
1.studio 的ndk環(huán)境配置。(下載,配置環(huán)境變量)
2在 gradle.properties 中加入 android.useDeprecatedNdk=true
3.在新建的項(xiàng)目中新建一個包含native 方法的類。(build一下)
public class PatchUtils {
static {
System.loadLibrary("自定義庫名");
}
public static native int patch(String oldApkPath, String newApkPath, String patchPath);
}
4.現(xiàn)在我們需要去生成一個.h文件,關(guān)聯(lián)對應(yīng)的native方法。(可以通過命令行,這邊用另外一種)
在setting-->Tools-->External tool--> "+" 中配置兩個命令。
5.1 javah($JdkPath$ 這個替代符可以在右側(cè)insert macro... 進(jìn)行選擇。)

5.2 ndk-build 的配置

6 在main 目錄下新建一個jni文件夾,然后右鍵含有native方法的類,選擇External tool,執(zhí)行javah命令(注意先Build),可以看到在jni 文件夾中生成了一個.h的頭文件。

接下來就是合成,(合成的關(guān)鍵還是用到原來bsdiff 工具中的c代碼)我們可以直接拷貝過來用。將其中bzip2文件夾拷貝到j(luò)ni中,留下文件夾中的.c .h文件。

在拷貝bspatch.c,引入剛剛生成的.h文件并實(shí)現(xiàn)他的方法體。(將該c文件中的main方法修改為applypatch)。
JNIEXPORT jint JNICALL Java_com_yang_patchtest_PatchUtils_patch(JNIEnv *env,
jobject obj, jstring old, jstring new, jstring patch) {
char * ch[4];
ch[0] = "bspatch";
ch[1] = (char*) ((*env)->GetStringUTFChars(env, old, 0));
ch[2] = (char*) ((*env)->GetStringUTFChars(env, new, 0));
ch[3] = (char*) ((*env)->GetStringUTFChars(env, patch, 0));
int ret = applypatch(4, ch);
(*env)->ReleaseStringUTFChars(env, old, ch[1]);
(*env)->ReleaseStringUTFChars(env, new, ch[2]);
(*env)->ReleaseStringUTFChars(env, patch, ch[3]);
return ret;
}
創(chuàng)建android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := patchLib
LOCAL_SRC_FILES := bspatch.c
include $(BUILD_SHARED_LIBRARY)
- 右鍵jni文件夾External tool 執(zhí)行ndk-build 命令,可以看到在libs 中生成我們的so文件。而這些so庫,即可用于我們客戶端的補(bǔ)丁合成了。

至此so庫已經(jīng)生成,那么我刪掉jni文件夾,便可以直接調(diào)用上面的native方法生成新的apk。
-----------------------------------------------分割----------------------------------------------------------
那假如我想把上面生成好的so 庫用到其他的app中呢:
我直接引用so 庫的話是不行的(當(dāng)然要是包名、類名以及方法名都一樣的話,就不說了)
這個過程和上面也是有點(diǎn)類似。
1 .前面5步驟都是一樣的。
2 .將需要的 so 文件以及對應(yīng)的.h文件(可有可無,只要知道方法名即可) 拷貝到j(luò)ni下的新建patches文件夾下。

2 再新建一個.c文件。 調(diào)用的so 庫中的方法
#include "patches/include/com_yang_patchtest_PatchUtils.h"
#include "com_yang_mypatch_PatchUtils.h"
JNIEXPORT jint JNICALL Java_com_yang_mypatch_PatchUtils_toPatch(JNIEnv *env,
jobject obj, jstring old, jstring new, jstring patch) {
return Java_com_yang_patchtest_PatchUtils_patch(env,obj,old,new,patch);
}
3 創(chuàng)建android.mk 和application.mk
android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := patchLib
LOCAL_SRC_FILES := patches/libpatchLib.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/patches/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := mypatches
LOCAL_SRC_FILES := mytest.c
LOCAL_SHARED_LIBRARIES := patchLib
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
application.mk
APP_STL:=gnustl_static
APP_CPPFLAGS:=-frtti -fexceptions
APP_ABI := armeabi
一般開發(fā)中只需要armeabi即可,當(dāng)然上面的so 庫也是armeabi的。
4.執(zhí)行前面講過的ndk-build 命令可以看到生成2 個so 庫。

5.刪掉jni文件夾,就可以直接使用so 了 (libs 要轉(zhuǎn)到app 下一級,gradle 要指定jniLibs。android studio 默認(rèn)是jniLibs)
關(guān)于mk文件的幾個重要參數(shù):
LOCAL_MODULE:模塊名稱。
LOCAL_SRC_FILES:參與編譯的源文件
APP_ABI:cpu架構(gòu)平臺類型。