一、前言
最近腾讯弄出一个Tinker热修复框架,那么本文先不介绍这个框架,先来介绍一下阿里的一个热修复框架AndFix,这个框架出来已经很长时间了,但是看网上没有太多非常详细的讲解,这里就来做一次分析。正好项目中要使用到。首先这个框架是开源的,可以在github上搜:AndFix 。其实在最早的时候我已经分析了阿里的另外一个热修复框架:Dexposed框架,还不了解的同学可以点击这里查看:Dexposed框架原理解析以及使用 当时介绍这个框架的时候发现他的实现原理很简单:
他的思想完全来源于Xposed框架,完美诠释了AOP编程,这里用到最核心的知识点就是在native层获取到指定方法的结构体,然后改变他的nativeFunc字段值,而这个值就是可以指定这个方法对应的native函数指针,所以先从Java层跳到native层,改变指定方法的nativeFunc值,然后在改变之后的函数中调用Java层的回调即可。实现了方法的拦截功能。
二、框架源码分析
那么本文介绍的AndFix框架相对于Dexposed框架来说又有什么区别呢?其实区别就在于AndFix框架更加轻便好用,在进行热修复的过程中更加方便了。当然这个优点在后面的Tinker框架也是能提现出来的。这个框架的原理是:直接在native层进行方法的结构体信息对换,从而实现完美的方法新旧替换,从而实现热修复功能。下面通过分析他的源码来看他的具体实现,下载完源码之后导入工程:
这里可以看到,因为在native层需要替换新旧方法结构体信息,所以这里肯定要做的工作就是虚拟机的兼容问题,这里做了art和dalvik的分开处理逻辑,下面来看一下这个框架的基本使用规则:
用法还是很简单的,这里的修复包是直接放在本地的,在实际操作中会从网上去下载。下面就开始分析源码,这里有一个主要的类就是PatchManager:
第一、PatchManager类初始化
在这个类的构造方法中做了两件事,一件事是初始化AndFixManager类,一件事是创建修复包存放的沙盒目录。这里先来看第二件事创建沙盒目录:
可以看到这个目录是:
/data/data/xxx/files/apatch/xxx.apatch
当我们从网上下载好修复包apatch文件之后,会调用addPatch方法,这时候会把修复包复制到这个地方,以后再次启动时就会遍历这个目录加载apatch文件。
第二、AndFixManager的初始化
下面继续来看AndFixManager初始化操作:
在这个初始化中也是干了两件事:一件事是判断当前环境是否支持热修复,一件事是初始化修复包安全校验的工作,先来看一下判断是否支持操作:
这里支持的条件是:非YunOS系统,Android2.3-7.0系统版本,热修复native层设置是否成功。这里我们看到应该值得关心的是setup操作,这个操作其实是native层进行的,可以直接看一下具体代码:
这里主要做了一些初始化操作,获取一些函数指针,准备后续的replaceMethod函数中使用:
1、在libdvm.so动态获取dvmDecodeIndirectRef函数指针和获取dvmThreadSelf函数指针。
2、调用dest的 Method.getDeclaringClass方法获取method的类对象clazz。
继续回到AndFixManager的初始化中的第二件事:修复包安全校验工作,其实这里只是做了初始化操作,而真正校验的工作在后面,主要是通过比对应用的签名和修复包的签名信息。后面再看吧!
第三:PatchManager的初始化操作