增量更新 也叫差分升级,通过某种算法,找出旧包和新包不一样的地方,然后生成差分包,这样用户下载的时候不需要下载完整大小的包到手机,只需要下载差分包,然后将差分包和本地的安装包合并成新的安装包,文件校验后安装。
bsdiff old.apk new.apk patch.apk
bspatch old.apk new.apk patch.patch
CMakeLists.txt
调动JNI的差分包合成的工具类
public class BsPatchUtils {
static {
System.loadLibrary("bspatch");
}
public static native int patch(String oldApk,String newApk,String patch_);
}
native-lib.cpp
#include <jni.h>
#include <string>
//告诉我们的程序在某个地方有实现patch方法
extern "C"{
//C++ C调用,包裹一下
extern int patch(int argc,char * argv[]);
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_ndk_BsPatchUtils_patch(JNIEnv *env, jclass clazz, jstring old_apk, jstring new_apk,jstring patch_) {
// TODO: implement patch()
// bspatch oldfile newfile patchfile
int argc=4;
char * argv[argc];
argv[0]="bspatch";
argv[1]= const_cast<char *>(env->GetStringUTFChars(old_apk, 0));
argv[2]= const_cast<char *>(env->GetStringUTFChars(new_apk, 0));
argv[3]= const_cast<char *>(env->GetStringUTFChars(patch_, 0));
//0表示成功
int result=patch(argc,argv);
//释放资源
env->ReleaseStringUTFChars(old_apk,argv[1]);
env->ReleaseStringUTFChars(new_apk,argv[2]);
env->ReleaseStringUTFChars(patch_,argv[3]);
return result;
}
java代码
File newFile = new File(getExternalFilesDir("apk"), "app.apk");//合成后的地址
File patchFile = new File(getExternalFilesDir("apk"), "patch.apk");//差分包下载保存地址获取
int result = BsPatchUtils.patch(getApplicationInfo().sourceDir, newFile.getAbsolutePath(),
patchFile.getAbsolutePath());
if (result == 0) {
install(newFile);
}
private void install(File file) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 7.0+以上版本
Uri apkUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", file);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
}
startActivity(intent);
}
-
合并的地方建议放在外置存储(SDcard)当中
-
合并的过程比较耗时,需要放到子线程中进行。