增量升级(省流量更新)的Java服务端实现
2013-05-02 02:24
337 查看
By sgwhp
(http://blog.csdn.net/sgwhp)转载请注明出处
用过类似360手机助手应该对省流量更新都很熟悉了。详细资料可以参考以下两个帖子:
浅析android应用增量升级
Android应用增量升级
本文需要详细说的是服务端的实现。如果对JNI还不了解的,建议先了解了JNI再看本文。
(2)除此之外,还需要下载bzip2。点击打开链接
(2)编译JDiff,并生成头文件:直接通过终端cd到JDiff.java所在目录,用javac编译。由于有package的存在,cd到src同级目录(上级目录),通过以下命令生成头文件。
成功到话会在src目录下生成test_JDiff.h。如果是在Windows下编译,不要-jni参数也是可以的。
(3)实现本地方法
解压下载到的bsdiff压缩包,提取其中到bsdiff.c到src目录下,名字随便取,为了保持一致,up主命名为“test_JDiff.c”。接下来根据我们刚刚生成到头文件对这个文件进行改造,实现我们定义到genDiff()方法。最简单的,我们将其中的main方法改名,这里命名为“genDiff”,加入头文件申明的genDiff()方法。最后还要导入“test_JDiff.h”和“jni.h”。具体实现如下:
(4)编译生成so
前面下载到bzip2到这儿就派上用场了,解压并提取其中的bzlib.c、bzip2.c、crctable.c、blocksort.c、compress.c、decompress.c、huffman.c、randtable.c(没有研究具体需要哪几个,前三个肯定是必需的,有兴趣的童鞋可以折腾折腾),同样是解压到src目录下。最后用gcc编译:
这个命令太长,为了方便查看,已经截断了。真正编译的时候不要有回车。简单说明这个gcc命令的几个参数:
“-I/usr/lib/jvm/java-7-sun/include/linux/” 和 “-I/usr/lib/jvm/java-7-sun/include/”把JNI的库引进来;
“-I/home/robust/workspace/Test/src”指名当前到路径,否则编译器找不到bzlib.c等文件的路径。
“libtest_JDiff.so”在Linux下,so的名称必需以lib开头,后面才是这个动态链接库真正的名称。
把生成的libtest_JDiff.so移至项目到根目录下。
(5)Java调用Native方法
准备某个应用的两个不同版本的apk,测试一下这个Native方法是否完成。编写一个测试类:
比较一下三个文件的大小:
(1)在Windows下重新编译一次,具体方法前面已经提到。
(2)使用这个包里的bsdiff.exe,通过Java的Runtime来调用。假设我们所有的文件,包括bsdiff.exe和其他apk都在d盘根目录,那么代码实现可以如下:
(http://blog.csdn.net/sgwhp)转载请注明出处
用过类似360手机助手应该对省流量更新都很熟悉了。详细资料可以参考以下两个帖子:
浅析android应用增量升级
Android应用增量升级
本文需要详细说的是服务端的实现。如果对JNI还不了解的,建议先了解了JNI再看本文。
1、准备工具
(1)bsdiff源码(点击下载)、某个应用的两个不同版本。或者直接下载上面提到的第一个博主提供的工具和素材。点击打开链接 这里面包括了我们需要用到的bsdiff源码和apk等。(2)除此之外,还需要下载bzip2。点击打开链接
2、编译环境
最好在Linux下编译。up主在Windows下面折腾过,表示装了MinGW也没用,很多库都没有。如果确实要在Windows下编译,可以参考这个GitHub项目到Compiling说明。当然了,都提到了JNI,Java的环境肯定也是必不可少的。3、编码实现
(1)创建Native方法类:up主用eclipse在test包下创建了JDiff.java类package test; public class JDiff { public static native int genDiff(String oldPath, String newPath , String patchPath); }
(2)编译JDiff,并生成头文件:直接通过终端cd到JDiff.java所在目录,用javac编译。由于有package的存在,cd到src同级目录(上级目录),通过以下命令生成头文件。
javah -jni test.JDiff
成功到话会在src目录下生成test_JDiff.h。如果是在Windows下编译,不要-jni参数也是可以的。
(3)实现本地方法
解压下载到的bsdiff压缩包,提取其中到bsdiff.c到src目录下,名字随便取,为了保持一致,up主命名为“test_JDiff.c”。接下来根据我们刚刚生成到头文件对这个文件进行改造,实现我们定义到genDiff()方法。最简单的,我们将其中的main方法改名,这里命名为“genDiff”,加入头文件申明的genDiff()方法。最后还要导入“test_JDiff.h”和“jni.h”。具体实现如下:
//导入库 #include <jni.h> #include <test_JDiff.h> #include <sys/types.h> #include <bzlib.h> #include <err.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> //重命名main方法 int genDiff(int argc,char *argv[]) {...} //实现本地方法 JNIEXPORT jint JNICALL Java_test_JDiff_genDiff (JNIEnv *env, jclass cls, jstring old, jstring new, jstring patch){ int argc=4; char * argv[argc]; argv[0]="bsdiff"; 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=genpatch(argc, argv); (*env)->ReleaseStringUTFChars(env,old,argv[1]); (*env)->ReleaseStringUTFChars(env,new,argv[2]); (*env)->ReleaseStringUTFChars(env,patch,argv[3]); return ret; }
(4)编译生成so
前面下载到bzip2到这儿就派上用场了,解压并提取其中的bzlib.c、bzip2.c、crctable.c、blocksort.c、compress.c、decompress.c、huffman.c、randtable.c(没有研究具体需要哪几个,前三个肯定是必需的,有兴趣的童鞋可以折腾折腾),同样是解压到src目录下。最后用gcc编译:
gcc -I/usr/lib/jvm/java-7-sun/include/linux/ -I/usr/lib/jvm/java-7-sun/include/ -I/home/robust/workspace/Test/src -fPIC -shared -o libtest_JDiff.so test_JDiff.c bzlib.c bzip2.c blocksort.c compress.c crctable.c decompress.c huffman.c randtable.c
这个命令太长,为了方便查看,已经截断了。真正编译的时候不要有回车。简单说明这个gcc命令的几个参数:
“-I/usr/lib/jvm/java-7-sun/include/linux/” 和 “-I/usr/lib/jvm/java-7-sun/include/”把JNI的库引进来;
“-I/home/robust/workspace/Test/src”指名当前到路径,否则编译器找不到bzlib.c等文件的路径。
“libtest_JDiff.so”在Linux下,so的名称必需以lib开头,后面才是这个动态链接库真正的名称。
把生成的libtest_JDiff.so移至项目到根目录下。
(5)Java调用Native方法
准备某个应用的两个不同版本的apk,测试一下这个Native方法是否完成。编写一个测试类:
package test; public class Test { static{ System.loadLibrary("test_JDiff");//装载动态链接库,记得把开头的“lib”去掉 } public static void main(String[] args){ JDiff.genDiff("old.apk", "new.apk", "patch.patch"); System.out.println("finished"); } }
比较一下三个文件的大小:
4、后话
由于增量包是的生成代码是在Linux下编译的,所以也只能在Linux下运行。如果要在Windows下运行,可以考虑以下两种方法:(1)在Windows下重新编译一次,具体方法前面已经提到。
(2)使用这个包里的bsdiff.exe,通过Java的Runtime来调用。假设我们所有的文件,包括bsdiff.exe和其他apk都在d盘根目录,那么代码实现可以如下:
Runtime rt = Runtime.getRuntime(); try { rt.exec("d:/bsdiff d:/old.apk d:/new.apk d:/patch.patch"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
相关文章推荐
- 增量升级(省流量更新)的Java服务端实现
- 【Android增量升级系列_02】 浅谈Android增量更新服务端的实现方法
- 增量升级(省流量更新)的Android客户端实现
- 增量升级(省流量更新)的Android客户端实现
- 增量升级(省流量更新)的Android客户端实现
- 增量升级(省流量更新)的Android客户端实现
- Android实现应用的增量更新\升级---其二
- Android实现应用的增量更新\升级---其一
- Android应用市场省流量更新(增量升级)原理解析
- 使用JAVA实现比较两个文件夹下的文件新增和修改情况,并复制到新的目录(实现增量更新项目)
- 【Android增量升级系列_01】 浅谈Android增量更新客户端的实现方法
- Android应用市场省流量更新(增量升级)原理解析
- Android--增量升级--增量更新客户端的实现方法
- 【Android增量升级系列_01】 浅谈Android增量更新客户端的实现方法
- 【Android增量升级系列_01】 浅谈Android增量更新客户端的实现方法
- android 增量更新之 服务端 附带java 调用示例
- Android实现应用的增量更新\升级
- 实现应用的增量更新\升级
- [置顶] Android实现应用的增量更新\升级 标签: 增量更新Androidbsdiffpatch增量升级 2016-01-25 16:01
- Android 版本更新之增量更新 包含java、.net服务端