热修复Tinker 原理解析之资源更新

本文详细探讨了Android Tinker的资源热更新原理,包括资源补丁的生成、下发后的合成以及补丁加载过程。讲解了ResDiffDecoder如何处理新旧资源文件,以及资源补丁如何在应用启动时被加载,确保资源更新生效。
摘要由CSDN通过智能技术生成

前言:之前已经在文章中对Tinker的Dex热更新的源码做了分析,今天接着开始对Tinker的资源热更新做源码的分析,废话就不多啰嗦了直接开始正文啦。

Android tinker接入使用

tinker之dex更新详解

tinker之so更新详解

一、资源补丁生成

友情提示:在上篇Dex分析的文章中已经介绍了生成补丁文件的开始流程,因此这里直接从ResDiffDecoder.patch(File oldFile, File newFile)开始分析。如果需要可以回头看一下Dex分析的文章内容。

ResDiffDecoder.patch(File oldFile, File newFile)主要负责资源文件补丁的生成,如果是新增的资源,直接将资源文件拷贝到目标目录;如果是修改的资源文件则使用dealWithModeFile函数处理。

// 如果是新增的资源,直接将资源文件拷贝到目标目录.
if (oldFile == null || !oldFile.exists()) {
    if (Utils.checkFileInPattern(config.mResIgnoreChangePattern, name)) {
        Logger.e("found add resource: " + name + " ,but it match ignore change pattern, just ignore!");
        return false;
    }
    FileOperation.copyFileUsingStream(newFile, outputFile);
    addedSet.add(name);
    writeResLog(newFile, oldFile, TypedValue.ADD);
    return true;
}
...
// 新旧资源文件的md5一样,表示没有修改.
if (oldMd5 != null && oldMd5.equals(newMd5)) {
    return false;
}
...
// 修改的资源文件使用dealWithModeFile函数处理.
dealWithModeFile(name, newMd5, oldFile, newFile, outputFile);

在dealWithModeFile中会对文件大小进行判断,如果大于设定值(默认100Kb),采用bsdiff算法对新旧文件比较生成补丁包,从而降低补丁包的大小;如果小于设定值,则直接将该文件加入修改列表,并直接将该文件拷贝到目标目录。

if (checkLargeModFile(newFile)) { //大文件采用bsdiff算法
    if (!outputFile.getParentFile().exists()) {
        outputFile.getParentFile().mkdirs();
    }
    BSDiff.bsdiff(oldFile, newFile, outputFile);
    //treat it as normal modify
    // 对生成的diff文件大小和newFile进行比较,只有在达到我们的压缩效果后才使用diff文件
    if (Utils.checkBsDiffFileSize(outputFile, newFile)) {
        LargeModeInfo largeModeInfo = new LargeModeInfo();
        largeModeInfo.path = newFile;
        largeModeInfo.crc = FileOperation.getFileCrc32(newFile);
        largeModeInfo.md5 = newMd5;
        largeModifiedSet.add(name);
        largeModifiedMap.put(name, largeModeInfo);
        writeResLog(newFile, oldFile, TypedValue.LARGE_MOD);
        return true;
    }
}
modifiedSet.add(name); // 加入修改列表
FileOperation.copyFileUsingStream(newFile, outputFile);
writeResLog(newFile, oldFile, TypedValue.MOD);
return false;

BsDiff属于二进制比较,其具体实现大家感兴趣的可以自行查看相关

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值