首先看create方法
这个大多数博客都有讲过,就是使用的java自己的动态代理,生成自定义的接口的具体实现类,并在执行接口中的方法的时候自动执行具体实现类的invoke方法,最终执行到InvocationHandler的invoke方法
引申:为什么动态代理只能够针对接口呢?
答:因为java是单继承,生成的动态代理类结构如下:
public final class $Proxy0 extends Proxy implements Interface {
public $Proxy0(InvocationHandler paramInvocationHandler) {
super(paramInvocationHandler);
}
}
如此一来,生成的类已经继承了Proxy,所以我们只能够以接口的方式将自己的方法来给代理类进行具体实现。
在loadServiceMethod中,Retrofit是将我们定义的接口中的方法进行缓存读取,有的话直接返回给我们进行API调用,为什么要缓存呢?因为制造一个注解解析,也就是parseAnnotation这段,代价是高昂的
这里可以看到,要解析注解,解析参数
解析注解又根据注解类型,分为如此之多的种类,这里我们接着看:
这里就是通过正则表达匹配来筛选出,而relativeUrl就是拼接到baseUrl的值
这里是不是看到熟悉的okhttp的Request.Builder了?所以也就是经过层层解析,将url还有参数,解析成okhttp可以使用的参数,最后交由okhttp进行网络请求。那么接下来再看看其他附带的参数有什么功能。
首先看确定返回值最重要的一个类:CallAdapter。我们都知道,Retrofit是通过构造者模式进行初始化的,CallAdapter是它的一个可选参数。类似这样:
那么看这个list到底有什么用呢?经过一番查找,发现只有一个地方用到了
从背景色的不同我们可以看出来,这个方法只有两个出口,一个是将CallAdapter返回,也就是我们自定义的CallAdapter工厂类根据不同返回值生产出来的CallAdapter,类似下图
而CallAdapter怎么确定自定义返回值类型呢?要知道,Okhttp只会返回Call<T>类型的返回值啊!这就用到了它巧妙的设计模式:适配器模式。
怎么理解设配器模式呢?其实没什么高大上,可以理解成在家里只有三个孔的插孔,但是你的手机充电器(自己需要的返回值类型)是两电脚,电脑是三电脚,那么手机就没法充电,于是我们买了一个拖线板(通用返回值类型),将手机充电器插到拖线板上,拖线板再连到插孔,就可以充电了!但是有的拖线板的两孔之间的距离可能生产得五花八门,于是就需要定义一个标准(接口),把两孔距离给定死。盗用一个图:
那么又有人说了,Call<T>不是已经可以自定义T的类型吗?为什么还要自定义CallAdapter呢?这就要从代码的可扩展性来看了,比如突然哪天学了RXJava,觉得很好用,就要使用Observable类型的返回值。
那么CallAdapter是在哪里起作用的呢?答案下图:
眼尖的童鞋可能已经看到了,parseAnnotations!这就是在解析接口的时候有调用的!至此CallAdapter已经完全摸通了,那么再看看另一个重要的类,Converter
上图我们已经看到了它的身影,那么就从这里直接进去
可以看到,思路跟CallAdapter一致,都是将自定义的Converter添加到list中,然后在解析的时候一个个进行返回值的比对,进行遍历返回,我们来看一下最常用的GsonConverterFactory里面是怎么实现的
很简洁,就是将解析的值写到responseBody中,那么来看看Converter在new添加进retrofit是怎么执行的
前面已经分析过了,跟CallAdapter一样,还是添加到list中
这里我们注意下,跟CallAdapter不一样的是,CallAdapter首先解析的是我们自定义的CallAdapter,找不到对应的CallAdapter才会去找defaultCallAdapterFactories,而ConverterFactories,我们可以看到,是先添BuiltInConverters,在添加我们自定义的Converter,最后使用默认的Converter。看看BuiltInConverter里面干了什么
isAssignableFrom是指前面一个类是否是后一个的父类或者接口,也就是说,如果responseBody是返回值类型的父类的话,就直接用ResponseBodyuConverter来进行解析,如下图
自定义的converter就不多说了,再看看platform.defaultConverterFactories()到底是个啥
我们可以看到,只有在SDK版本大于24的时候才会有,而OptionalConverterFactory中
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
just将ResponseBody转换成Object,好吧,虽然大部分情况不会走到这里,不然肯定要检查自己的返回值是否正确