热修复Tinker(二)补丁包加载源码分析

热修复Tinker(二)补丁包加载源码分析,第1张

<p>

前面一篇Tinker相关的文章已经介绍了Tinker热修复框架的使用与整个的修复流程,那么这一篇就要开启Tinker的源码解析之路了。

首先简单说一下Tinker的原理,Tinker其实也是类似multidex的dex方式,将目标dex插入到数组最前面,主要是通过对比原dex文件(存在bug)与现dex文件(bug已修复)生成差异包,生成的差异包作为补丁包下发给客户端,客户端做一系列校验之后,将下发的差异包与本应用的dex文件合并成成全量的dex文件,并进行opt优化,当再次启动APP时候则加载优化过的全量dex文件,将dex文件插入到DexPathList 中 dexElements的前面。

所以Tinker其实是两个流程,一个是加载补丁包,另外一个是加载dex文件,两个的加载流程相对较长,这里分开说明,这一篇呢,主要介绍加载补丁包的流程。

<p>

加载补丁包的方法如下

往下看发现调用了TinkerInstaller的onReceiveUpgradePatch方法

TinkerInstaller.java

这里调用了PatchListener的onPatchReceived方法

而PatchListener是一个接口,他的具体实现为SamplePatchListener方法,onPatchReceived在SamplePatchListener的父类DefaultPatchListener有实现,我们看下DefaultPatchListener中的onPatchReceived方法

如下

DefaultPatchListener.java

首先这个检测了一下这个插件是否可用,通过SamplePatchListener的patchCheck方法来检测

SamplePatchListener.java

这里对插件是否可用进行了判断,就不进行详细分析了

当插件可用时候returnCode为ERROR_PATCH_OK,当不可用则会log出来失败的errorcode

成功则调用

来启动TinkerPatchService这个IntentService,并且把插件的路径给传递到IntentService

TinkerPatchService通过onHandleIntent来接收传递过来的数据

TinkerPatchService.java

这里首先调用了PatchReporter的onPatchServiceStart方法,而PatchReporter的实现为SamplePatchReporter

SamplePatchReporter.java

这里主要看UpgradePatchRetry的onPatchServiceStart方法

UpgradePatchRetry.java

这里主要也做了一些验证,并且把文件复制一份到/data/data/tinker.sample.android/tinker_temp/路径下,然后把相关信息写入到配置文件中

在回到TinkerPatchService的onHandleIntent方法

主要看

这个方法的实现在UpgradePatch中

UpgradePatch.java

这里首先初始化相关数据与相关验证,再将补丁文件拷贝到目标目录中

路径为/data/data/tinker.sample.android/tinker/patch-xxxxxx/patch-xxxxxx.apk

接下来就是调用DexDiffPatchInternal,BsDiffPatchInternal,ResDiffPatchInternal这些类的方法进行dexDiff差分的计算相关

至于相关差分的计算,由于比较复杂,我暂时还没有深入去看,暂时埋个坑在这里,等后面找时间去填上这个坑

在回到TinkerPatchService的onHandleIntent方法

后面调用了PatchReporter的onPatchResult,这个方法主要删除了上面拷贝在/data/data/tinker.sample.android/tinker_temp/的文件

接下来启动了AbstractResultService,并把插件的路径传递过去了

AbstractResultService的实现在SampleResultService类里面,SampleResultService的onPatchResult删除了原始的插件文件。

到这里插件加载分析就基本结束了

<p>

插件加载分析结束了,但是却没有去分析dexDiff差分的计算,而这个dexDiff差分计算则是区分的Tinker与其他相同方案的热修复库,dexDiff是基于 Dex 的文件结构来下手,将产生变化的结构提取出来,产生的补丁非常小,而且在 diff 的过程中也处理了一些会造成补丁包很大的场景,所以等后面有时间将这一块补上,下一篇文章则是对dex文件加载进行源码分析了,peace~~~

长话短说:

因为一般游戏启动时会提示丢失的那些dll严格来讲都不算是系统文件,微软原版系统刚安装完的时候本来就不存在那些dll,其实不是“丢失”,就是原本就没有,需要自己另外安装的。

举个栗子,比如很多老游戏需要dx9运行库,二win8.1系统本身只自带dx11,没有老旧的9.0版,就会出现提示丢失d3dx9之类的dll

msvcp、msvcr、vcomp140.dll属于VC++2015版

msvcp、msvcr、vcomp120.dll属于VC++2013版

msvcp、msvcr、vcomp110.dll属于VC++2012版

msvcp、msvcr、vcomp100.dll属于VC++2010版

msvcp、msvcr、vcomp90.dll属于VC++2008版

msvcp、msvcr60、71和80.dll,以及vcomp.dll(不带数字版本号)属于VC++2005版

除了丢失、缺少这类错误之外,如果一个程序打开之后提示“并行配置错误”,那么也是因为没有安装VC++运行库。

缺少PhysXLoader.dll是NVIDIA PhysX物理加速引擎的问题

提示没有找到xlive.dll是缺少Games For Windows Live

缺失 openal32.dll是缺少OpenAL Installer for Windows的原因

此文件本质上是dll运行库的一部分,丢失、缺失此类文件都是dll运行库的问题,而不是游戏本身的问题。所以重新下游戏肯定是没有用的。

并且,有些人建议的重装系统大法也是没用的(指原版系统,换系统除外)。

因为这些所谓的dll丢失,绝大部分都并不是真的“丢失”,而是原版系统本身确实就没有自带。

建议使用dll修复工具,解压之后打开主程序点击“修复”按钮,稍等即可解决。

关于附件:dll运行库修复工具是很容易搜到下载的,也可以直接下载我附件(上传附件仅仅是为了下载方便,也可以直接搜索下载),附件免费下载,不要积分。7z、rar、zip文件要用解压缩软件打开,x86版就是32位版,请不要再问出“为什么只有86位版”之类搞笑的问题。

很多人喜欢传播“下载dll放到system32或syswow64”这种解决办法,倒也不是完全不可行,有时候还是可以的,要看运气。对小白来讲还是麻烦了点,而且不像修复工具一样能一次性搞定大部分dll运行库的相关问题。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11158009.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-14
下一篇 2023-05-14

发表评论

登录后才能评论

评论列表(0条)

保存