项目中要使用Tinker作为补丁的解决方案,所以把Tinker进行了简单的解读。
将原来的Application类隔离起来,即其他任何类都不能再引用我们自己的Application。我们需要做的其实是以下几个工作:
将我们自己Application类以及它的继承类的所有代码拷贝到自己的ApplicationLike继承类中,例如SampleApplicationLike。你也可以直接将自己的Application改为继承ApplicationLike;
Application的attachBaseContext方法实现要单独移动到onBaseContextAttached中;
对ApplicationLike中,引用application的地方改成getApplication();
对其他引用Application或者它的静态对象与方法的地方,改成引用ApplicationLike的静态对象与方法;
ApplicationLike类中注解了在manifest中注册的Application,然后通过注解处理器处理后继承与TinkerApplication。
DefaultApplicationLike是Application中生成的代理类,去实现一些初始化等项目要处理的操作。T调用TinkerLoader的tryLoad方法
context.getApplicationInfo().dataDir主程序的私有目录,否则DexClassLoader可能会拒绝加载
TinkerDexLoader.loadTinkerJars
包含判断是否是art平台
SystemClassLoaderAdder.installDexes
PathClassLoader
分版本加载
TinkerResourceLoader.loadTinkerResources
TinkerResourcePatcher.monkeyPatchExistingResources
取得AssetManager对象,assets.addAssetPath(resDir)这句话的意思是把文件里的资源都加载到AssetManager对象中来使用,这里引申至可以换皮肤,换语言包,动态加载apk等
TinkerInstaller.onReceiveUpgradePatch合成
TinkerPatchService补丁合成服务
UpgradePatch合成逻辑
dalvik.system.DexFile
loadDex
public static DexFile loadDex (String sourcePathName, String outputPathName, int flags)
打开一个DEX文件,并提供一个文件来保存优化过的DEX数据。如果优化过的格式已存在并且是最新的,就直接使用它。如果不是,虚拟机将试图重新创建一个。
该方法主要用于应用希望在通常的应用安装机制之外下载和执行DEX文件。不能在应用里直接调用该方法,而应该通过一个类装载器例如dalvik.system.DexClassLoader.
Tinker使用的是PathClassLoader
LoadReporter类定义了Tinker在加载补丁时的一些回调,可以继承DefaultLoadReporter实现自己的事件回调.
回调运行在加载的进程,它有可能是各个不一样的进程。我们可以通过tinker.isMainProcess或者tinker.isPatchProcess知道当前是否是主进程,patch补丁合成进程。
回调发生的时机是我们调用installTinker之后,某些进程可能并不需要installTinker。
PatchReporter类定义了Tinker在修复或者升级补丁时的一些回调,可以继承DefaultPatchReporter实现自己的事件回调
sUpgrade:区分补丁合成的类型。是由于文件丢失而发起的RepariPatch, 还是收到新的补丁而发起的UpgradePatch
PatchListener类是用来过滤Tinker收到的补丁包的修复、升级请求,也就是决定是不是真的要唤起:patch进程去尝试补丁合成
若检查成功,会调用TinkerPatchService.runPatchService唤起:patch进程,去尝试完成补丁合成操作。反之,会回调检验失败的接口。事实上,你只需要复写patchCheck函数即可。若检查失败,会在LoadReporter的onLoadPatchListenerReceiveFail中回调
AbstractResultService类是:patch补丁合成进程将合成结果返回给主进程的类。