Android平臺下合併patch差分包
一、添加文件
將 bzip2 的所有 .c 和 .h 文件以及bspatch.c 複製到Android Studio 的 cpp 目錄下(記得修改main方法名,保證只有一個main入口)
二、在Cmake.txt中鏈接所有文件
使用
file(GLOB c_path src/main/cpp/*.c)
可以將所有文件添加爲一個 c_path 路徑變量
file(GLOB c_path src/main/cpp/bzip2/*.c)
add_library( # Sets the name of the library.
bspacth-lib
SHARED
${c_path}
src/main/cpp/bspatch.c)
add_library( # Sets the name of the library.
native-lib
SHARED
src/main/cpp/native-lib.c)
find_library( # Sets the name of the path variable.
log-lib
log)
target_link_libraries( # Specifies the target library.
native-lib
bspacth-lib
${log-lib})
三、調用bspatch中的main方法
將 bspatch.c 中的 main 方法改名爲 bspatch_main
創建一個native方法並實現內容
public static native int bsPatch(String oldPath, String newPath, String patchPath);
//bspatch已動態註冊
JNIEXPORT int JNICALL
bspatch(JNIEnv *env, jclass type, jstring jst_oldPath,
jstring jst_newPath, jstring jst_patchPath) {
char *oldPath = (char *) (*env)->GetStringUTFChars(env, jst_oldPath, NULL);
char *newPath = (char *) (*env)->GetStringUTFChars(env, jst_newPath, NULL);
char *patchPath = (char *) (*env)->GetStringUTFChars(env, jst_patchPath, NULL);
int ret;
int arg = 4;
char *argv[4];
argv[0] = "bspatch";
argv[1] = oldPath;
argv[2] = newPath;
argv[3] = patchPath;
ret = bspatch_main(arg, argv);
(*env)->ReleaseStringUTFChars(env, jst_oldPath, oldPath);
(*env)->ReleaseStringUTFChars(env, jst_newPath, newPath);
(*env)->ReleaseStringUTFChars(env, jst_patchPath, patchPath);
return ret;
}
System.loadLibrary("native-lib")
System.loadLibrary("bspatch-lib")
//直接把apk和差分文件放入sdk進行合併測試
val oldPath = SDK_CARD_PATH + File.separator + "appOld.apk"
val newPath = SDK_CARD_PATH + File.separator + "appNew.apk"
val patchPath = SDK_CARD_PATH + File.separator + "apk.patch"
FileUtils.bspatch(oldPath,newPath,patchPath)
正常情況下apk安裝之後在系統中存在一份備份,應該用此備份作爲oldPath,patch文件也應該從服務端下載,這裏偷個懶。
/**
* 獲取已安裝Apk文件的源Apk文件
* 如:/data/app/my.apk
*
* @param context
* @param packageName
* @return
*/
public static String getSourceApkPath(Context context, String packageName) {
if (TextUtils.isEmpty(packageName))
return null;
try {
ApplicationInfo appInfo = context.getPackageManager()
.getApplicationInfo(packageName, 0);
return appInfo.sourceDir;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
四、安裝合併之後的apk
/**
* 安裝Apk
*
* @param context
* @param apkPath
*/
public static void installApk(Context context, String apkPath) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + apkPath),
"application/vnd.android.package-archive");
context.startActivity(intent);
}