您好,欢迎来到化拓教育网。
搜索
您的当前位置:首页Android Studio 2.2 NDK入门(二) 增量更新

Android Studio 2.2 NDK入门(二) 增量更新

来源:化拓教育网

基础回顾

增量更新原理

有太多的介绍了,简而言之就是生成差分表,合并差分包.本文主要讲解app端实现合并差分包

相关c文件及工具

  • 客户端合并差分包源码:
  • 服务端生成差分包源码及工具:
  • 我的服务器为centos64位,在source目录下直接使用make编译即可。如果是windows系统,可以使用visual studio之类的工具编译

开始增量更新之旅

  • 接上一篇的项目继续玩耍
  • 首先将合并差分包的c源码添加进app
diff.png
  • 编写客户端的差分包合并代码,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转换的c和头文件.h
    参考第一篇中的javah方式
    javah -d jni class.package.ClassName
    生成的文件和函数应该类似这样的: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);
        }
    }
  • 调用合并,这里应该是现在完毕后自动合并。还应该判断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_PatchUtilsJava_com_custom_package_utils_PatchUtils_func

结语

  • demo地址为
  • 水平有限,欢迎多多提意见和建议。

Copyright © 2019- huatuo9.cn 版权所有 赣ICP备2023008801号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务