Tinker
优势:基于classloader的classlaoder开发了自己的classlaoder,基于原声的aapt开发了自己的aapt.基于自己的dex文件格式,研发了dexdiff算法
使用流程:集成sdk→配置gradle→初始化tinker(applicaiton)→构建tinker的gradle→TinkerPatch.with().fetchPatchUpdate(true);
Tinker的问题:
1.不支持加固
2.不支持修改清单文件
3.不支持新增四大组建,动画,桌面图标
4.三星android-21不兼容
源码:通过TinkerInstaller完成初始化和加载Patch文件
初始化:Tinkerinstaller是一个外观模式,它所有的方法都是调用tinker这个类来完成的。通过Tinkerinstaller.install方法吧所有的参数传入tinker的构建者模式中以完成初始化。Tinker是一个单例和构建者完成的(whitn单例 builder构建者)
加载patch文件:TinkerInstaller.onReceiveUpgradePatch方法中通过Tinker,with.getPatchListener.onPatchReceiver来加载文件和监听加载的回调。onPatchReceiver是一个接口,被DefaltPatchListener实现。在onPatchReceiver中调用TinkerPatchService.runPatchService来启动TinkerPatchService来完成patch文件的加载与合并。启动了TinkerPAtchService后,它的onHandlerIntent中会处理 “加载合并patch文件”这些耗时操作。核心的处理方法是upgradePatchProcessor的tryPatch方法,它是一个抽象方法,被upgradeParch实现。
tryPatch中有三个方法分别对应不同文件的处理
1.DexDiffPatchIntenal.tryRecoverDexFIles 处理 dex 文件。这个方法中的patchDexExtractViaDexDiff通过调用extractFiddInternals中的PatchDexFile中的DexPatchApplier类来完成加载。这个类中有15个算法用来处理不同类型的内容。(修复机制:把patchFile的dex文件保存到它所有字段的一个offset,把patch的dex文件的所有区的offset全部标记出来,.把app的dex文件的所有区的offset标记出来,传入算法,算法通过write,update,处理对应字段,再通过execute把修改写入本地)
2.dexDiffPatchInternal.tryrecoverLibaryFiles处理libary文件
3.DexDiffPatchInternal.tryRecoverResourceFiles处理资源文件,通过patchResourceExtractViaResourceDiff中的extractResourceDiffInternals方法,经过一系列初始化,然后通过ResUtil.extractTinkerEntry完成清单文件,新增资源,修改资源。extractTinkerEntry中通过IO流把所有的修改写入apk的arsc文件中