美文网首页NDK && JNIAndroid进阶之路Android知识
Android Studio 2.2 NDK入门(二) 增量更新

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

作者: wecode | 来源:发表于2017-04-24 12:17 被阅读57次

    基础回顾

    Android Studio 2.2 NDK入门(一) 官方DEMO解析 http://www.jianshu.com/p/021ab5c67d8f

    增量更新原理

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

    相关c文件及工具

    开始增量更新之旅

    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

    结语

    相关文章

      网友评论

        本文标题:Android Studio 2.2 NDK入门(二) 增量更新

        本文链接:https://www.haomeiwen.com/subject/gfwuzttx.html