Retrofit 源码大解析

首先看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,好吧,虽然大部分情况不会走到这里,不然肯定要检查自己的返回值是否正确

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
android期末大作业源码是我花了数周时间精心编写的。这个项目是使用Android Studio开发的一个应用程序,实现了许多功能和特性。在源码中,你可以看到我使用了Java和XML来编写各种页面和逻辑代码。比如,我使用了RecyclerView来展示一系列数据,使用了Fragment来实现页面的切换,还用了AsyncTask来完成后台数据的处理。此外,我还为应用添加了一些动画效果,以提升用户体验。 在源码中,你还能看到我添加了一些第三方库和插件来完善应用功能,比如Glide用来加载图片,Retrofit用来处理网络请求,以及ButterKnife用来简化View的绑定操作。除此之外,我还利用了Android SDK提供的各种API来实现一些高级功能,比如定位、相机、推送等。整个项目的结构清晰,功能模块分明,代码规范。 另外,我也在源码中添加了一定的注释,以便其他人能够更容易地理解我的代码逻辑和实现思路。同时,为了保证代码的质量和性能,我还进行了一定的优化和重构。源码中包含了应用的各个界面的布局文件、逻辑代码、资源文件等等。 总的来说,这个android期末大作业源码是我在学期中所学习的Android开发知识的一个展示,通过这个项目,我不仅巩固了所学的内容,也学到了很多新的技能和经验。希望这份源码能够展现我对Android开发的热爱和专业能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值