windows下Android studio增量更新及NDK环境搭配

最近看了安卓增量更新的文章,自己尝试了下,无奈自己用的windows的系统,出现了各种问题,经过查资料,终于成功,现在总结下并分享下经验。(参考鸿洋的增量更新博客)

首先我们配置下NDK的环境,配置好的同学请下翻

  • 下载NDK环境
    Android studio的SDK自带NDK的开发包,我们只需要下载就可以了,打开SDKmanger,选择SDKTools,将CMAKE,LLDB,NDK勾选,然后点击OK,就会开始下载。
    windows下Android studio增量更新及NDK环境搭配_第1张图片
  • 创建NDK项目
    下载完成后,我们创建一个NDK的项目(我是在原来的项目基础上写的,所以我还是按我的编程的顺序来截图),编写调用的Activity
public class IncrementalUpdate extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView content=new TextView(this);
        content.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                doBspatch();
            }
        });
        content.setText(R.string.incrementalupdate);
        setContentView(content);
    }


    private void doBspatch() {
        final File destApk = new File(Environment.getExternalStorageDirectory(), "dest.apk");
        final File patch = new File(Environment.getExternalStorageDirectory(), "PATCH.patch");

        //一定要检查文件都存在

        BsPatch.bspatch(ApkExtract.extract(this),
                destApk.getAbsolutePath(),
                patch.getAbsolutePath());

        if (destApk.exists())
            ApkExtract.install(this, destApk.getAbsolutePath());
    }
}

上文中BsPatch类是调用NDK的,ApkExtract类是安装应用的,贴代码
BsPatch.java类

public class BsPatch {

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

    public static native int bspatch(String oldApk, String newApk, String patch);

}

ApkExtract.java类

public class ApkExtract {
        public static String extract(Context context) {
            context = context.getApplicationContext();
            ApplicationInfo applicationInfo = context.getApplicationInfo();
            String apkPath = applicationInfo.sourceDir;
            Log.d("hongyang", apkPath);
            return apkPath;
        }


    public static void install(Context context, String apkPath) {
        Intent i = new Intent(Intent.ACTION_VIEW);
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.setDataAndType(Uri.fromFile(new File(apkPath)),
                "application/vnd.android.package-archive");
        context.startActivity(i);
    }
}
  • 生成 .h 文件
    到现在我们的java代码已经差不多了,我们开始生成JNI调用的头文件,用CMD一直cd到我们的class文件所在的位置,但是只要cd到debug下就停止,然后用javah -jni com.xx.xx.BsPatch就会生成 .h 文件,在debug文件夹下能看到头文件,贴图
    windows下Android studio增量更新及NDK环境搭配_第2张图片

生成好的头文件,如图
windows下Android studio增量更新及NDK环境搭配_第3张图片

  • 创建JNI文件夹
    头文件我们是有了,然后我们在项目的main文件夹下创建一个文件夹,命名为jni
    windows下Android studio增量更新及NDK环境搭配_第4张图片
    将刚才的头文件拷贝到该目录下面

  • JNI编写前的准备(bsdiff和bzip2)
    在编写C代码前,我们先要下载两个文件,一个是bsdiff,一个bzip2,注意,这两个文件是linux上的文件,将下载好的两个文件在ubuntu系统上提取出来,将bsdiff-4.3下的bspatch.c拷贝出来放到我们studio的jni目录下待用,然后在jni目录下建一个文件夹,命名为bzip2,然后再回到ubuntu系统将bzip2-1.0.5文件夹下的C文件(.c)和头文件(.h)提取出来,拷贝到我们刚才再studio上建好的bzip2的文件夹下,还是贴上图吧
    ubuntu上文件体系
    windows下Android studio增量更新及NDK环境搭配_第5张图片

studio拷贝好的文件目录
windows下Android studio增量更新及NDK环境搭配_第6张图片
- C代码的编写
准备工作就绪,下来我们就编写C代码,其实没啥编写的,我们打开bspatch.c,先给他加上

#include "jni.h"
#include "bzip2/bzlib.h"
#include "com_test_util_BsPatch.h"

第二步,复制下面的代码到bspatch.c

JNIEXPORT jint JNICALL Java_com_test_util_BsPatch_bspatch
        (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));


    int ret = patchMethod(argc, argv);

    (*env)->ReleaseStringUTFChars(env, old, argv[1]);
    (*env)->ReleaseStringUTFChars(env, new, argv[2]);
    (*env)->ReleaseStringUTFChars(env, patch, argv[3]);
    return ret;
}

第三步,保险起见,找到com_test_util_BsPatch.h,我的是这个哈,你们的就不一定了,就因为不一定,所以可能会错,复制BsPatch.h方法名替换上图中的方法的名字(Java_com_test_util_BsPatch_bspatch)

  • 编写MK文件
    MK文件直接上图,其实我也不懂,先来Android.MK的
LOCAL_PATH      := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bzip2/blocksort.c \
                   bzip2/bzip2.c \
                   bzip2/bzip2recover.c \
                   bzip2/bzlib.c \
                   bzip2/compress.c \
                   bzip2/crctable.c \
                   bzip2/decompress.c \
                   bzip2/dlltest.c \
                   bzip2/huffman.c \
                   bzip2/mk251.c \
                   bzip2/randtable.c \
                   bzip2/spewG.c \
                   bzip2/unzcrash.c
LOCAL_LDLIBS    := -lm -llog -ljnigraphics
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/bar
include $(BUILD_SHARED_LIBRARY)


include $(CLEAR_VARS)
LOCAL_MODULE    := bsdiff
LOCAL_SRC_FILES := bspatch.c
LOCAL_LDLIBS    := -lm -llog -ljnigraphics
LOCAL_SHARED_LIBRARIES := bar
include $(BUILD_SHARED_LIBRARY)

下面的是Application.mk的

APP_ABI     := all
APP_PLATFORM:= android-19
APP_OPTIM   := release
  • 剩下要说的
    这个是不需要配build.gradle的,但是没有添加C++support的同学要link一下,选择的时候注意选MK文件,我们的MK就是Android.MK,还有,要在gradle.properties文件的末尾加上,注意android的a是小写的
android.useDeprecatedNdk=true

下来尽情的编译吧
windows下Android studio增量更新及NDK环境搭配_第7张图片

so文件的位置

windows下Android studio增量更新及NDK环境搭配_第8张图片

测试项目

  • 测试前准备
    我们先回到ubuntu系统,将先前下载并提取的文件进行编译(编译命令请百度),编译好后,将上面studio的项目打包个APK,然后在项目基础上添加或修改一些东西(最好比较明显的体现增量更新成功,比如字体换个颜色)后,生成APK,将2个Apk放在ubuntu的同一个目录下,然后cd到该目录下执行以下命令

    bsdiff old.apk new.apk old-to-new.patch

    然后将old.apk和old-to-new.patch同时放在手机SD卡下,并安装old.apk,注意看activity的代码,你会发现要给这两个文件改下名字的old.apk–>dest.apk和old-to-new.patch–>PATCH.patch

运行触发代码自己看看效果吧!如果有问题,欢迎回复哈

你可能感兴趣的:(心得体会)