bsdiff的编译网上有很多直接参考,贴一个链接,mac环境和linux环境下都写的很详细。
https://blog.csdn.net/weixin_30414635/article/details/95086119
在Android 平台下的使用。
首先在我们从1.0到2.0版本升级,我们需要打出差分包,上传到服务器,用户登陆时根据自己的版本号去服务器下载对应的差分包,使用bspatch把差分包和旧的apk包,合成最新的apk后安装。这样实现首先可以避免去商城下载,其次下载的大小和时间节省了,也减轻了后台服务器负担。
创建android ndk工程。把 bspatch.c 拿到工程中来,这时候编译会出错,提示找不到xxx头文件,然后去bzip2去找。
我配置完后的工程结构信息如下:
这里会提前把差分包打好,我这里放到sdcard下,实现热更新。
public void onUpdate(View view) {
new AsyncTask<Void, Void, File>() {
@Override
protected File doInBackground(Void... voids) {
String path = getApplication().getApplicationInfo().sourceDir;
bspatch(path, "/sdcard/new.apk", "/sdcard/patch.diff");
return new File("sdcard/new.apk");
}
@Override
protected void onPostExecute(File file) {
super.onPostExecute(file);
Intent intent = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
} else {
// 声明需要的临时权限
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// 第二个参数,即第一步中配置的authorities
String packageName = getApplication().getPackageName();
Uri contentUri = FileProvider.getUriForFile(MainActivity.this, packageName + ".fileProvider", file);
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
}
startActivity(intent);
}
}.execute();
}
bspatch(path, "/sdcard/new.apk", "/sdcard/patch.diff"); 是一个native方法。合成新apk,然后执行安装。
extern "C" {
int main(int argc, char *argv[]);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_disssample_MainActivity_bspatch(JNIEnv *env, jobject thiz, jstring oldpath,
jstring newpath,
jstring patch_path) {
const char *oldPath = env->GetStringUTFChars(oldpath, 0);
const char *newPath = env->GetStringUTFChars(newpath, 0);
const char *patchPath = env->GetStringUTFChars(patch_path, 0);
char *argv[4] = {"", const_cast<char *>(oldPath), const_cast<char *>(newPath),
const_cast<char *>(patchPath)};
main(4, argv);
env->ReleaseStringUTFChars(oldpath, oldPath);
env->ReleaseStringUTFChars(newpath, newPath);
env->ReleaseStringUTFChars(patch_path, patchPath);
}
这里就是拿到老版本,生成的新版本和差分包的路径,传入main中,这个main方法就是bspatch中的main方法。
在命令行执行:bspatch oldpath newpath patchpath 可以合成新的apk,这里是四个参数,所以main方法中传递的就是这四个参数。