retrofit整体代码量不是很大,但是涉及到的知识点还是很多的,也是一款很好的解耦封装框架,在其中是能够学习到很多东西的,当前鉴于时间原因先重点分析retrofit的流程逻辑实现,里面的涉及到的知识点后续会有文章分析学习(水平有限,有些可能分析不到位,欢迎小伙伴指正讨论,喷就没必要了吧)。
-
从组建者模式浅谈retrofit对象的组建
retrofit实例创建
- 如上代码所示,retrofit很明显是build(组建者模式),组建者模式特性:
* builder模式通常对象内部存在builder组建类,通常是static修饰,可以通过对象直接访问,还可能设置成为final,不能被继承修改。
* builder内部属性api通常是链性的,可以链式调用
* builder除了内置属性设置外,比较特殊的就是构造方法和组建方法build(),retrofit我们也是重点分析这两个api。 -
构造方法Builder():
retrofit builder api
承接上文* 如图所示:下面的builder构造方法接受platform作为参数,而上面而是传入的platform.get(),继续向下跟Platform这个对象做什么用:
Platform的get api
findPlatform()
Android对象* 通过Android handler实现的默认回调线程是Android的ui线程。在Android平台retrofit会将响应的数据自动切回到ui线程,所以使用rxjava+okhttp+retrofit要切实分析其接口请求和接口响应都在那一个线程中,不然极其容易出问题,接口请求通常要么是rxjava(外部线程处理)或者okhttp异步处理,retrofit是不处理接口请求的线程逻辑,但是retrofit是处理了接口返回的线程(无论请求什么线程都会将响应切回UI线程)。
- builder对象通过一系列的set api对其属性进行设置赋值,具体api在上面图片介绍上都添加了注释,不再一一解释。
-
builder即时没有设置其属性,在对象组建方法build中每一个属性也有其对应的默认赋值,build方法如下:
build方法实现* 简要分析api的实现,外面用户没有设置的情形下,判空后将callFactory指向了okhttpClient,后续callAdapter和CovertAdapter都将默认的实例类添加到了对应的list列表中去。
- 由上面的步骤我们就获取到了retrofit的示例对象,将设置其对应的上下文环境,默认的call示例和默认的covert实例。
-
通过反射,注解,抽象代理等技术retrofit创建声明的接口的一个实例对象并实现内部的api方法,根据方法的注解将其封装到okhttpcall对象。
retrofit创建抽象接口对象
- 这一块是retrofit的核心代码,也是难点最多的代码,涉及到java的反射,注解等,设计模式的抽象代理,水平有限这一块只能说一下个人的简单理解,更多的是流程逻辑的实现,具体细节实现分析后续单开文章消化解析。
-
由上面的可知入口方法是create,下面是create的代码实现:create方法实现
- api首先对于创建的类进行校验处理,即validateServiceInterface的实现:validateServiceInterface
-
通过抽象代理创建接口的实例对象及其对应方法的实现,这一块当前还不熟暂不详细分析,这段代码流程逻辑是先反射实现声明的方法,然后校验方法是否是默认方法,java对于默认方法的理解是有具体的实现的方法就是默认方法,接口中一般声明的都不是默认方法,所以第三个圈中不会处理,会直接走到loadService方法,这方法上面校验接口类的时候又出现,主要处理了方法的注解解析。下面跟着去看这个方法的实现:
loadService - 方法使用容器及类单例实现了方法的唯一,这个后续有篇文章分析使用容器实现多方法或者多对象的唯一性实现
-
抛去上面描述的,方法的核心实现集中在ServiceMethod.parseAnnotations(this, method),继续向下跟:
ServiceMethod - 这个api方法比较简单明了,主要做个两步:
* 将接口中声明的注解http协议,header协议,接口参数等解析并封装到对应的RequestFactory中去。
* 将上面的requestfactory和method和retrofit串联起来,包括calladapter(回调类型),covertadapter(回调数据转换)和okhttpcall绑定在一起。 - 当篇文章简单分析retrofit的实现能够更有利于后面的retrofit的使用和学习retrofi的实现思路,后续两个api就不跟了,后面注解的详细解析及其串联绑定,上面的流程也更流畅。
-
rotrofit如何实现同步和异步接口请求访问的
retrofit的请求实现
-
由第二个小章节可以知道接口访问retrofit最终是关联到okhhtp,这个章节可以更好的验证retrofit将最后的接口请求还是交给okhttp处理的,首先看一下call的api集合:
call抽象接口如图所示,接口中定义了两个api一个是execute另一个是enqueue,这两个表示同步和异步调用看api就和okhttp的同步/异步接口访问很相似。
-
接下来重点去看call的okhhtp实现类okhttpcall对其api的实现,即:okhhtpcall的execute的实现
* okhhtpcall创建后只能执行一次这个逻辑和okhhtp也很相似,第一步先是验重,校验当前是否已经执行过。
* 创建okhttp的call对象,createRawCall的具体实现是:
* okhttpcall是否创建失败根据其失败类型返回不同的异常报警。
createRawCall的实现
* 调用上面创建的okhttp3的call对象的execute方法将接口请求交接给okhhtp处理并获取其response进行后续的解析,解析流程下个章节再去分析。 - enqueue异步调用和同步execute流程基本类似。
-
okhttp响应数据怎么转换成为retrofit对象的
responce响应解析
- 代码比较简单也比较清晰,就是对okhttp请求后的响应数据进行解析并根据不同的响应码对上层进行响应,即:
* http响应码成功都在200到300之间,所以不在此范围内的响应接口失败并将对应的响应数据对外提供
* 204/205两个响应码比较特殊,是接口成功但是没有具体的响应数据,此时直接对外响应成功并将数据对外响应,不进行转换。
* 针对200的其他情况,将其封装到ExceptionCatchingResponseBody中去,该封装类持有responsebody并对其进行读取并获取内容类型和内容大小,内容不可读则进行异常抓取。
* 上一步没有出现异常的情况下进行下一步的逻辑操作,将其交给转换器进行转换操作。
* 异常校验封装类和平时写法不太一样,平时通常都是和下面的convert同时写到一个try catch中去,仔细想想好像也没什么不同。
* 将转换后的对象响应给用户。