Andoird Eclipse下增量升级解析

来源:互联网 发布:ne452cha支持什么网络 编辑:程序博客网 时间:2024/06/03 17:46

今天突发兴致的想搞一搞,安卓增量升级这个东西,之前听说过就想搞一搞,奈何拖了好久。今天下定决心搞一搞。废话不说了,搞搞更健康。

一、增量增量更新浅谈
增量更新的原理非常简单,简单的说就是通过某种算法找出新版本和旧版本不一样的地方(这个过程也叫做差分),然后将不一样的地方抽取出来形成所谓的更新补丁(patch),也称之为差分包。客户端在检测到更新的时候,只需要下载差分包到本地,然后将差分包合并至本地的安装包,形成新版本的安装包,文件校验通过后再执行安装即可。本地的安装包通过提取当前已安装应用的apk得到。想要了解更多关于增量更新的概念性。可以自己去百度下哈。

增量更新的流程是:用户手机上安装着某个应用,下载了增量包,手机上的apk和增量包合并形成新的包,然后再次安装(注意这个过程是要重新安装的,当然部分应用市场有root权限你可能感知不到)。
那么把整个流程细化为几个关键点:
用户手机上提取当前安装应用的apk
如何利用old.apk和new.apk生成增量文件
增加文件与1.中的old.apk合并,然后安装
解决了上述3个问题,就ok了。

二、增量更新的SO编译
开始之前需要先下载两个资源,即bsdiff以及bszip的源码。这边提供下载地址
bsdiff的源码:
http://download.csdn.net/detail/wjb201314/9906395
bszip的源码:
http://download.csdn.net/detail/wjb201314/9906449
下载完成,解压就行。新建个项目,然后新建一个带有native声明的类(我这边叫BsPatchUtil)。然后在这个类里添加以下代码

 static {        System.loadLibrary("bsdiff");    }    public static  native int patch(String oldApkPath, String newApkPath, String patchPath);

先不用管方法里三个参数的含义。其实根据名字,我们大概可以知道是什么意思了。后面再说。
在工程目录下,新建一个jni文件夹。打开我们刚才下载的bszip源码。把目录下的一个bspatch.c复制到jni目录下。在里面添加以下代码

JNIEXPORT jint JNICALL Java_com_example_zlupdate_BsPatchUtil_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));        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;    }

Java_com_example_zlupdate_BsPatchUtil_patch这个要和你建的包名和类名和方法名一致。patchMethod(argc, argv)在.c文件里是没有这个方法的,其实这个就是main方法,只要把.c文件里的mian改成patchMethod就行。

然后新建一个bspatch.h文件(也可以配置javah生成一个跟bspatch同名的.h文件)。添加以下代码

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_example_zlupdate_BsPatchUtil */#ifndef _Included_com_example_zlupdate_BsPatchUtil#define _Included_com_example_zlupdate_BsPatchUtil#ifdef __cplusplusextern "C" {#endif/* * Class:     com_example_zlupdate_BsPatchUtil * Method:    patch * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I */JNIEXPORT jint JNICALL Java_com_example_zlupdate_BsPatchUtil_patch  (JNIEnv *, jclass, jstring, jstring, jstring);#ifdef __cplusplus}#endif#endif

打开刚才下载解压后的bszip源码。把里面的.c文件和.h文件全部拷到你的jni目录下。
完成上述步骤,我们就可以来编写我们的mk文件了。在jni目录下新建一个Application.mk文件。在里面添加APP_ABI := all这行代码,表示生成各个平台的so文件。再新建一个Android.mk文件。在里面添加以下代码

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := bsdiffLOCAL_SRC_FILES := bspatch.c\                    bzlib.c\                    blocksort.c\                    compress.c\                    crctable.c\                    decompress.c\                    huffman.c\                    randtable.c\                    bzip2.c\  # No static libraries.  LOCAL_STATIC_LIBRARIES := \libbz  # Also need the JNI headers.  LOCAL_C_INCLUDES += \$(JNI_H_INCLUDE) external/bzip2  # No special compiler flags.  LOCAL_CFLAGS +=  include $(BUILD_SHARED_LIBRARY)

LOCAL_MODULE := bsdiff表示你要生成so文件的名字。
接着配置NDK(前提是你已经安装了ndk)。新建并配置一个新的Builder
1) 点击Project->Properties->Builders->New,新建立一个Builder。在弹出的对话框上面点击Program,点击OK;
2) 在弹出的对话框【Edit Configuration】中,配置选项卡【Main】:
Location中需要填入nkd-build.cmd的路径(NDK安装目录下)。
WorkingDiretcoty中需要填入HelloJni的工程根目录。
3) 在【EditConfiguration】中,配置选项卡【Refresh】:
勾选“Refresh resources upon completion”,
勾选“The entire workspace”,
勾选“Recuresively include sub-folders”。
4)在【EditConfiguration】中,配置选项卡【Build Options】:
勾选“After a “Clean””,
勾选“During manual builds”,
勾选“During auto builds”,
勾选“Specify working set of relevant resources”。
点击“Specify Resources…”勾选TestNDK工程的“jni“目录,Finish!
保存设置,点击OK。
5) 、生成so文件
由于我们勾选了“During auto builds”,所以在工程有所改变的时候,so文件便会自动编译,正确生成以后就能在工程目录下发现多了两个文件夹,文件夹libs\armeabi目录下生成了一个叫libhello-jni.so的文件。至此,使用NDK生成so文件的工作就完成了。
6)、so文件的调用
在BsPatchUtil.java文件中有一段代码:
static {
System.loadLibrary(“bsdiff”);
}
使用loadLibrary就可以加载该so文件了,加载的时候不需要写libbsdiff.so,只要写bsdiff就可以了。

好了,完成上诉的so文件的编译。我紧接着去利用工具生成一个patch.patch文件(这个就是增量文件。)。要生成这个增量文件我们需准备以下材料,一个旧的apk和一个新的apk,还有一个用来生成增量文件的工具。这里提供工具的下载
http://download.csdn.net/detail/wjb201314/9906408
下载完后直接解压就行。然后新建了一个项目,用来做增量升级测试。把上面我们生成的so文件拷贝到我们新建的工程项目下的lib目录下的armeabi目录下。把之前为了编译so新建的一个带有native声明的BsPatchUtil直接拷贝到我们的工程目录下,当然这个类的包名要跟之前的一致(即在工程目录下新建一个同样的包名,然后把这个类拷进去)。否则会报错。然后在MainActivity里添加一个按钮,用来触发增量升级。在按钮的点击事件里添加以下代码

 final File destApk = new File(Environment.getExternalStorageDirectory(), "new.apk");            final File patch = new File(Environment.getExternalStorageDirectory(), "patch.patch");              if (destApk.exists()&&patch.exists()){            BsPatchUtil.patch(ApkExtract.extract(this),destApk.getAbsolutePath(),patch.getAbsolutePath());             ApkExtract.install(this, destApk.getAbsolutePath());        }        ```新建一个 ApkExtract类,添加以下代码:

package com.example.activitytest;

import java.io.File;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.net.Uri;
import android.util.Log;

public class ApkExtract {
/**
*
* @Title: extract
* @Description: 提取当前应用的apk
* @param @param context
* @param @return 参数
* @return String 返回类型
* @throws
*/
public static String extract(Context context){
context = context.getApplicationContext();
ApplicationInfo applicationInfo = context.getApplicationInfo();
String apkPath = applicationInfo.sourceDir;
Log.d(“ApkExtract”, apkPath);
return apkPath;
}
/**
*
* @Title: install
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param @param context
* @param @param apkPath 参数
* @return void 返回类型
* @throws
*/
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);
}
}

“`
记得要在xml配置文件里添加sd卡读写权限
完成上述步骤,就可以开始导apk了。先导出一个apk,命名为old.apk。然后随便在按钮的点击事件里添加个吐司,再导出apk,命名为new.apk.好了,现在有了旧的和新的apk。现在利用我们刚才下载的工具,来生成一个patch.patch文件。把上面导出的两个apk放在解压后生成的目录下。

这里写图片描述
然后进入到在cmd里输入bsdiff old.apk new.apk patch.patch。就可以在该工具目录下生成一个patch.patch文件
这里写图片描述
这里写图片描述
好了,此时我们得到一个old.apk、new.apk、patch.patch.最后把new.apk、patch.patch分别放在
这里写图片描述
这定义的目录下(可以自己定义)。然后安装old.apk,打开应用点击按钮就可以执行增量更新测试了。
这里写图片描述
这里写图片描述
好了,增量升级到这里就大功告成了。

原创粉丝点击