Android增量更新 – 客户端使用bsdiff差分包与原包合并

bsdiff简介

Android增量更新需要用到二进制差分工具:bsdiff

bsdiff and bspatch are tools for building and applying patches to binary files.

官方网站:http://www.daemonology.net/bsdiff/
bsdiff for windows:http://www.pokorra.de/coding/bsdiff.html

Android版本区别设定

(1)旧版本

app.gradle

versionCode 1
versionName "1.0"

activity_main.xml

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="20dp"
    android:text="1.0版本"
    android:textSize="16sp"
    android:textColor="#3BC1FF"
    />

(2)新版本

添加资源文件:assets/cctv.mp4

app.gradle

versionCode 2
versionName "2.0"

activity_main.xml

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="20dp"
    android:text="2.0版本"
    android:textSize="16sp"
    android:textColor="#3BC1FF"
    />

NDK实现pacth

Java层声明native方法

public class BsPatch {

    /**
     * 合并
     * @param oldFilePath
     * @param newFilePath
     * @param patchFilePath
     */
    public static native void patch(String oldFilePath, String newFilePath, String patchFilePath);

    static {
        System.loadLibrary("BsPatch");
    }
}

C层合并算法实现:diffupdate.c

您需要先支付 1元 才能查看此处内容!

立即支付
已支付?点击这里查询

Java层调用bspatch实现bsdiff差分包与原包合并

class AppUpdateTask extends AsyncTask<Void, Void, Boolean> {
    @Override
    protected Boolean doInBackground(Void... params) {
        //1. 下载差分包
        Log.i(TAG, "开始下载");
        //File patchFile = DownloadUtil.download(PATCH_URL);
        //String patchFilePath = patchFile.getAbsolutePath();
        Log.i(TAG, "下载完成");
        //2. 获取旧版本已经安装的apk文件(/data/app/)
        String oldApk = ApkUtil.getSourceApkPath(MainActivity.this, getPackageName());
        Log.i(TAG, "Old Apk: " + oldApk);
        //3. 合并:oldFile+patchFile->newFile
        BsPatch.patch(oldApk, NEW_APK_PATH, PATCH_FILE_PATH);
        Log.i(TAG, "合并完成");
        try {
            Log.i(TAG, "New Apk MD5: " + MD5Util.getFileMD5String(NEW_APK_PATH));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        if (!result) {
            Toast.makeText(MainActivity.this, "差分包合并失败", Toast.LENGTH_SHORT).show();
        }
        //1. 获取两个版本的签名进行对比
        //获取已经安装应用的签名
        String oldSign = SignUtil.getInstalledApkSignature(MainActivity.this, getPackageName());
        //获取未安装Apk文件的签名
        String newSign = SignUtil.getUnInstalledApkSignature(NEW_APK_PATH);
        if (TextUtils.equals(newSign, oldSign)) {
            //2. 安装
            ApkUtil.installApk(MainActivity.this, NEW_APK_PATH);
        } else {
            Toast.makeText(MainActivity.this, "签名不匹配", Toast.LENGTH_SHORT).show();
        }
        Toast.makeText(MainActivity.this, "差分包合并成功", Toast.LENGTH_SHORT).show();
    }
}

app.gradle 配置

defaultConfig {
    ...
    externalNativeBuild {
        cmake {
            cppFlags "-frtti -fexceptions"
            abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a'
        }
    }
}

externalNativeBuild {
    cmake {
        path "CMakeLists.txt"
    }
}

安装测试

> adb push diff.patch /sdcard/  //将差分包导入到SD卡中,模拟在线更新
[100%] /sdcard/diff.patch

> adb install DiffUpdate_v1.apk  //安装旧版Apk以待测试增量更新
[100%] /data/local/tmp/DiffUpdate_v1.apk
        pkg: /data/local/tmp/DiffUpdate_v1.apk
Success

>

运行日志输出,可以看到合并生成的 New Apk MD5 与服务器端合并生成的完全一致

cc.androidios.diffupdate I/yezhou: Old Apk: /data/app/cc.androidios.diffupdate-1/base.apk
cc.androidios.diffupdate I/yezhou: 合并完成
cc.androidios.diffupdate I/yezhou: New Apk MD5: 735a02764167048e738a7f6ea99f2b86

核心技术点

bspatch功能调用

bspatch的使用方法为

bspatch oldfile newfile patchfile

bspatch.c的main函数为其入口函数,这里将函数名改为bspatch_main,变为普通函数,即可实现被其它函数调用。

int bspatch_main(int argc, char * argv[])

CMakeLists.txt 配置

您需要先支付 1元 才能查看此处内容!

立即支付
已支付?点击这里查询

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/05/01/android-incremental-update-client-merge-bsdiff-differential-package-with-original-package/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Android增量更新 – 客户端使用bsdiff差分包与原包合并
bsdiff简介 Android增量更新需要用到二进制差分工具:bsdiff bsdiff and bspatch are tools for building and applying patches to binary files. 官方网站:h……
<<上一篇
下一篇>>
文章目录
关闭
目 录