Android 生成差分包

来源:互联网 发布:查看阿里云ecs数据库 编辑:程序博客网 时间:2024/05/29 19:09

原博客地址:http://blog.csdn.net/u013705351/article/details/22722499


如果没用增量升级,我们的升级流程是这样的:

1、打包好apk上传到服务器,设置apk版本

2、客户端发现服务器端有高版本apk。

3、直接下载最新版本apk提示安装

这个过程中,在服务器端只是保存一个历史版本的记录,这样的确也简单。

但是直接下载apk,发现有个问题就是apk很大的时候,下载的时间比较长,所以才会有了查分升级


如果采用查分升级,我们的升级流程就变成这样了:

         1、打包好apk上传至服务器,设置版本号。

         2、对所有旧版本都生成对应的patch(差分)文件,如果上传之前已经有n个版本,要对这n个版本都要生成差分包

         3、客户端发现服务端有高版本apk。

         4、客户端通过当前版本找到对应的patch文件下载。

         5、客户端对patch文件和旧的apk进行合并。

  6、合并之后提示安装


package redis;import java.io.BufferedOutputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.security.MessageDigest;import com.nothome.delta.Delta;import com.nothome.delta.DiffWriter;import com.nothome.delta.GDiffPatcher;import com.nothome.delta.GDiffWriter;public class DiffTool {    private final static char[] hexChar = { '0', '1', '2', '3', '4', '5', '6',            '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };    private static String toHexString(byte[] b) {        StringBuilder sb = new StringBuilder(b.length * 2);        for (int i = 0; i < b.length; i++) {            sb.append(hexChar[((b[i] & 0xF0) >>> 4)]);            sb.append(hexChar[(b[i] & 0xF)]);        }        return sb.toString();    }    public static String getMD5(File file) {        InputStream fis = null;        String str = null;        try {            fis = new FileInputStream(file);            byte[] buffer = new byte[1024];            MessageDigest md5 = MessageDigest.getInstance("MD5");            int numRead = 0;            while ((numRead = fis.read(buffer)) > 0) {                md5.update(buffer, 0, numRead);            }            str = toHexString(md5.digest());        } catch (Exception e) {            e.printStackTrace();        } finally {            if (fis != null) {                try {                    fis.close();                } catch (Exception e) {                }            }        }        return str;    }    private static File mergeFile(final String source, final String patch,            String target) throws Exception {        GDiffPatcher patcher = new GDiffPatcher();        File deffFile = new File(patch);        File updatedFile = new File(target);        patcher.patch(new File(source), deffFile, updatedFile);        return updatedFile;    }    public static File mergeApk(final String source, final String patch,            final String target, String newApkMd5) throws Exception {        File updateFile = mergeFile(source, patch, target);        String ufpMd5 = getMD5(updateFile);        System.out                .println("服务端下发的md5:" + newApkMd5 + ",新合并后的apk MD5:" + ufpMd5);        if (ufpMd5 == null || !newApkMd5.equalsIgnoreCase(ufpMd5)) {            if (updateFile.exists()) {                updateFile.delete();            }            throw new Exception("MD5错误,不能成功合并!");        }        return updateFile;    }    /**     * 生成差分包:old_new.patch = diff(old.apk, old.apk)     *      * */    private static void createPatch(String oldApkName, String newApkName,            String patchName) {        System.out.println("开始生成差分包");        long start = System.currentTimeMillis();        try {            File newApk = new File("Max1.0.1040.apk");            File oldApk = new File("Max1.0.0000.apk");            File patchFile = new File("old_new.patch");            DiffWriter output = null;            output = new GDiffWriter(new DataOutputStream(                    new BufferedOutputStream(new FileOutputStream(patchFile))));            if (oldApk.length() > Integer.MAX_VALUE                    || newApk.length() > Integer.MAX_VALUE) {                System.err                        .println("source or target is too large, max length is "                                + Integer.MAX_VALUE);                System.err.println("aborting..");            }            Delta d = new Delta();            d.compute(oldApk, newApk, output);            System.out.println("差分包生成完成,完成耗时:"                    + (System.currentTimeMillis() - start) + "ms");        } catch (Exception e) {            e.printStackTrace();        }    }    public static void main(String args[]) throws Exception {        String newApkName = "Max1.0.1040.apk";        String oldApkName = "Max1.0.0000.apk";        String patchName = "old_new.patch";        String targetApkName = "new.apk";        try {            createPatch(oldApkName, newApkName, patchName);            String newApkMd5 = getMD5(new File(newApkName));            mergeApk(oldApkName, patchName, targetApkName, newApkMd5);        } catch (Exception ioe) { // gls031504a            System.err.println("error while patching: " + ioe);        }    }}


         

0 0
原创粉丝点击