前言
从上文的一些知识中,知道,真正的Application是注解生成的,并且继承与TinkerApplication。那么我们就来分析下。
attachBaseContext
首先看attachBaseContext这个方法。
|
|
- 设置UncaughtExceptionHandler
- 调用onBaseContextAttached方法。
onBaseContextAttached方法代码如下:
|
|
- 获取系统已运行时间,作为applicationStartElapsedTime
- 获取系统当前时间,作为applicationStartMillisTime
- loadTinker() load tinker
- ensureDelegate 确认下delegate是否没有初始化
- 调用applicationLike的onBaseContextAttached方法,对应demo中的SampleApplicationLike的onBaseContextAttached方法。
- 如果是安全模式,就获取当前进程名,preferName,并将安全模式count置为0。
loadTinker
代码如下:
|
|
- 首先判断flag,如果为TINKER_DISABLE,直接return
- 生成tinkerLoadClass的Class
- 获得tryLoad方法的Method
- 获取tinkerLoadClass的构造方法
- 调用tryLoad方法返回Intent对象
ensureDelegate
|
|
在这个方法中,会判断applicationLike是不是null,如果是的话,就调用createDelegate去创建一个代理对象。
|
|
在这个方法中,通过反射构造出一个代理对象,根据demo传入的参数,这里构造出来的对象,是SampleApplicationLike。
在看下SampleApplicationLike的构造方法吧。
|
|
参数很明显,我们还需要看下继承关系。SampleApplicationLike->DefaultApplicationLike->ApplicationLike,ApplicationLike实现了ApplicationLifeCycle的一系列接口。这个接口完全按照Application的一些方法,比如onCreate,onLowMemory等等。
SampleApplicationLike的构造方法会调用父类的构造方法,最后调用到ApplicationLike的。
|
|
这里就是把参数进行初始化。
SampleApplicationLike#onBaseContextAttached
|
|
- 首先调用MultiDex.install方法
- 然后初始化一些个参数
- 调用TinkerManager的一些方法来初始化或者设置一些值
- 然后installTinker
- 生成一个Tinker对象
###
小结
从逻辑流程来看,核心部分在于TinkerLoadeClass的tryLoad,以及TinkerManager的一些方法。其他的方法就是做一些初始化之类的工作,当然,这些也很重要。
TinkerLoader#tryLoad方法
|
|
这个方法内部主要是调用tryLoadPatchFilesInternal方法,
|
|
这个方法的代码特别长,但是逻辑并不是特别复杂:
- 首先获取patchDirectoryFile,为/data/user/0/packageName/tinker
- 获取patchInfoFile、patchInfoLockFile等等
- 获取旧版本号、新版本号等信息
- 获取其他的一些信息
- 进行一些so、dex、resource的check
- 然后进行load操作
- 将结果写入intent返回
TinkerManager的一些方法
主要是进行参数设置以及Tinker的install操作,Tinker的install操作,由TinkerInstaller的install方法完成。
TinkerApplication的其他方法
在这里的其他方法中,我们看到的代码几乎都是将这些操作,委托(代理)SampleApplicationLike中对应的方法来完成。
总结
过程如下,先loadTinker,在这里面会进行tryLoad操作,然后在创建代理对象,最后调用applicationLike的#onBaseContextAttached方法来初始化TinkerManager以及Tinker的安装。