基礎回顧
Android Studio 2.2 NDK入門(一) 官方DEMO解析 http://www.reibang.com/p/021ab5c67d8f
增量更新原理
有太多的介紹了畜普,簡而言之就是生成差分表均践,合并差分包.本文主要講解app端實現(xiàn)合并差分包
相關c文件及工具
- 客戶端合并差分包源碼:https://github.com/gosttusng/JNI_/tree/master/app/src/main/cpp/diff
- 服務端生成差分包源碼及工具:https://github.com/gosttusng/JNI_/tree/master/source
- 我的服務器為centos64位,在source目錄下直接使用make編譯即可鬓梅。如果是windows系統(tǒng)溯祸,可以使用visual studio之類的工具編譯
開始增量更新之旅
- 接上一篇的項目繼續(xù)玩耍http://www.reibang.com/p/021ab5c67d8f
- 首先將合并差分包的c源碼添加進app
- 編寫客戶端的差分包合并代碼坟比,PatchUtils.java
public class PatchUtils {
static PatchUtils instance;
public static PatchUtils getInstance() {
if (instance == null)
instance = new PatchUtils();
return instance;
}
static {
System.loadLibrary("ApkDiff");
}
/**
* native方法 使用路徑為oldApkPath的apk與路徑為patchPath的補丁包,合成新的apk妻枕,并存儲于newApkPath
*
* 返回:0僻族,說明操作成功
*
* @param oldApkPath
* 示例:/sdcard/old.apk
* @param newApkPath
* 示例:/sdcard/new.apk
* @param patchPath
* 示例:/sdcard/xx.patch
* @return
*/
public native int patch(String oldApkPath, String newApkPath, String patchPath);
}
- 使用javah自動生成ndk轉(zhuǎn)換的c和頭文件.h
參考第一篇中的javah方式
javah -d jni class.package.ClassName
生成的文件和函數(shù)應該類似這樣的:com_example_mobaolibo_jni_bsdiff_PatchUtils.c/h
JNIEXPORT jint JNICALL
Java_com_example_mobaolibo_jni_bsdiff_PatchUtils_patch(JNIEnv *, jclass, jstring, jstring, jstring);
JNIEXPORT jint JNICALL
Java_com_example_mobaolibo_jni_bsdiff_PatchUtils_patch(
JNIEnv *env,
jclass cls,
jstring old,
jstring new,
jstring patch){
int argc = 4;
char * argv[argc];
argv[0] = "bspatch";
argv[1] = (char*) ((*env)->GetStringUTFChars(env, old, 0));
argv[2] = (char*) ((*env)->GetStringUTFChars(env, new, 0));
argv[3] = (char*) ((*env)->GetStringUTFChars(env, patch, 0));
printf("old apk = %s \n", argv[1]);
printf("patch = %s \n", argv[3]);
printf("new apk = %s \n", argv[2]);
int ret = applypatch(argc, argv);
printf("patch result = %d ", ret);
(*env)->ReleaseStringUTFChars(env, old, argv[1]);
(*env)->ReleaseStringUTFChars(env, new, argv[2]);
(*env)->ReleaseStringUTFChars(env, patch, argv[3]);
return ret;
}
- 新建一個任務用來合并差分包
public class PatchTask extends AsyncTask<String, Void, Integer> {
@Override
protected Integer doInBackground(String... params) {
try {
int result = PatchUtils.getInstance().patch(srcDir, newDir, patchDir);
if (result == 0) {
handler.obtainMessage(1).sendToTarget();
return WHAT_SUCCESS;
} else {
handler.obtainMessage(2).sendToTarget();
return WHAT_FAIL_PATCH;
}
} catch (Exception e) {
e.printStackTrace();
}
return WHAT_FAIL_PATCH;
}
@Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
loading.setVisibility(View.GONE);
}
}
- 調(diào)用合并,這里應該是現(xiàn)在完畢后自動合并屡谐。還應該判斷md5等等述么。這里僅作演示
public void patch(View view){
loading.setVisibility(View.VISIBLE);
new PatchTask().execute();
}
實際應用需要注意
- 編譯成.so文件供其它項目使用時,需要注意
com_example_mobaolibo_jni_bsdiff_PatchUtils.c
的類包名和路徑要匹配愕掏,不然會報錯No implementation found
- 舉個例子:項目中是的patchUtils.java路徑為
com.custom.package.utils.PatchUtils.java
,則javah
生成的文件中和名字均是com_custom_package_utils_PatchUtils
碉输,Java_com_custom_package_utils_PatchUtils_func
結(jié)語
- demo地址為https://github.com/gosttusng/JNI_.git
- 水平有限,歡迎多多提意見和建議亭珍。