【React Native】差量热更新(二)

上一篇介绍了在Windows平台上生成diff.zip和diffMD5.txt的生成工具,接下来介绍在移动端如何使用diffMD5.txt和diff.zip来merge资源和bundle文件,从而差量热更新。

按照惯例,先讲一下整体思想:
1、下载MD5文件,与本地MD5文件进行比对,如果相同,不需要下载diff.zip包,如果不同下载diff.zip
这里下载MD5文件和比对的逻辑就不再赘述。同样,下载diff.zip的逻辑也不再赘述。
2、将下载出来的diff.zip进行处理(核心逻辑)
(1)、将diff.zip进行解压
(2)、将目前的bundle文件和资源文件进行备份,为将来的回滚处理做准备(目前没有操作)
(3)、合并bundle文件
(4)、合并资源文件
(5)、备份MD5文件
(6)、删除diff.zip的解压文件夹

下面将主要介绍(1)、(3)、(4)的核心逻辑代码:

(1)、将diff.zip解压缩:解压缩的时候只需要注意一点,及目录结构的还原:如压缩时文件的目录为res/drawable-xhdpi/image.png,压缩后中间文件夹均会消失,同时文件名称改为res/drawable-xhdpi/image.png,在解压缩时需要将文件名重新还原成原来的目录结构。

public static boolean decompression(String zipFile, String folderPath) throws ZipException, IOException {
        ZipFile zfile = new ZipFile(zipFile);
        Enumeration zList = zfile.entries();
        ZipEntry ze = null;
        byte[] buf = new byte[1024];
        while (zList.hasMoreElements()) {
            ze = (ZipEntry) zList.nextElement();
            String zeName = ze.getName();
            String basePath = folderPath;
            if (zeName.contains("\\")) {
                String[] dirsNames = zeName.split("\\\\");
                for (int i=0;i<dirsNames.length;i++) {
                    if (i == dirsNames.length-1) {
                        zeName = dirsNames[i];
                        continue;
                    }
                    basePath = basePath + File.separator + dirsNames[i];
                    createDir(basePath);
                }
            }
            OutputStream os = new BufferedOutputStream(
                    new FileOutputStream(getRealFileName(basePath, zeName)));
            InputStream is = new BufferedInputStream(zfile.getInputStream(ze));
            int readLen = 0;
            while ((readLen = is.read(buf, 0, 1024)) != -1) {
                os.write(buf, 0, readLen);
            }
            is.close();
            os.close();
        }
        zfile.close();
        return true;
    }

(3)、合并bundle文件:

public void mergeBundle(Context context) {
        String currentBundleFilePath = FileUtils.getCurrentBundleFilePath(context);
        String diffBundleFilePath = FileUtils.getDiffBundleFilePath(context);
        if ("".equals(currentBundleFilePath) || "".equals(diffBundleFilePath)) {
            return;
        }

        BundleDiffMerge.bundleDiffMerge(currentBundleFilePath,diffBundleFilePath,currentBundleFilePath);//合并bundle文件的核心代码
    }
/**
     * @param oldBundlePath 为oldBundle
     * @param diffBundlePath 为diffBundle
     * @param outputPath 为输出newBundle路径
     */
    public static void bundleDiffMerge(String oldBundlePath,String diffBundlePath,String outputPath) {
        String oldPath = oldBundlePath;
        String diffPath = diffBundlePath;

        diff_match_patch dmp = new diff_match_patch();
        //将text diff转换为patch
        LinkedList<diff_match_patch.Patch> pathes = (LinkedList<diff_match_patch.Patch>) dmp.patch_fromText(DiffUtils.getStringFromPat(diffPath));
        //与旧bundle合并  生成新bundle
        Object[] bundleArray = dmp.patch_apply(pathes,getJsBundleFromAssets(oldPath));
        try {
            File outputFile = new File(outputPath);
            if (!outputFile.exists()) {
                outputFile.createNewFile();
            }
            Writer writer = new FileWriter(outputPath);
            String newBundle = (String) bundleArray[0];
            writer.write(newBundle);
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

(4)、合并资源文件

private void mergeRes(Context context) {
        String diffResDirPath = FileUtils.getDiffResDirPath(context);
        if ("".equals(diffResDirPath)) {
            Log.e("------","没有需要merge的资源");
            return;
        }
        File resFile = new File(diffResDirPath);
        if (resFile.isDirectory()) {
            for (File file : resFile.listFiles()) {
                if (file.isDirectory() && file.getName().contains("drawable")) {
                    //只copy drawable相关的资源文件
                    com.gome.work.diff.utils.FileUtils.copyDir(file.getAbsolutePath(),FileUtils.getRootFile(context).getAbsolutePath() + "/" + file.getName());
                }
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值