Android Retrofit 源码分析

一、retrofit 是什么?

Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。 网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装。

1)App应用程序通过 Retrofit 请求网络,实际上是使用 Retrofit 接口层封装请求 参数、Header、Url 等信息,之后由 OkHttp 完成后续的请求操作。

2)在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit,Retrofit根据用 户的需求对结果进行解析。

二、retrofit 总流程:

1)通过解析网络请求接口的注解,配置网络请求参数;

2)通过动态代理生成网络请求对象;

3)通过网络请求适配器将网络请求对象进行平台适配;

4)通过网络请求执行器发送网络请求;

5)通过数据转换器解析服务器返回的数据;

6)通过回调执行器切换线程(子线程 ->>主线程);

7)用户在主线程处理返回结果。

三、代理实例创建过程

1:成功建立一个Retrofit对象的标准:配置好Retrofit类里的成员变量

baseUrl:网络请求的url地址

callFactory:网络请求工厂

callbackExecutor:回调方法执行器

adapterFactories:网络请求适配器工厂的集合

converterFactories:数据转换器工厂的集合

2:创建了一个ISharedListService接口类的对象,create函数内部使用了动态代理来创建接口对象,这样的设计可以让所有的访问请求都被代理。

通过 Retrofit. create( ciass)方法创建出 Service interface 的实例,从而使得 Service 中配置的方法变得可用,这是 Retrofit 代码结构的核心;Retrofit.create()方法内部,使用的是Proxy.newProxylnstancef)方法来创建Service 实例。这个方法会为参数中的多个 interface (具体到 Retrofit 来说,是固定传入一个interface)创建一个对象,这个对象实现了所有 interface 的每个方法,并且每个方法的实现都是雷同的:调用对象实例内部的一个工 nvocationHandler 成员变量的 invoke()方法,并把自己的方法信息传递进去。这样就在实质上实现了代理逻辑:interface 中的方法全部由一个另外设定的 InvocatioriHandler 对象来进行代理操作。并且,这些方法的具体实现是在运行时生成 interface 实例时才确定的,而不是在编译时(虽然在编译时就已经可以通过代码逻辑推断出来)。这就是动态代理机制的具体含义。

四、访问接口创建过程

Call<SharedListBean>sharedListCall=sharedListService.getSharedList(2,1);

调用getSharedList的时候,在动态代理里面,会存在一个函数getSharedList,这个函数里面会调用invoke,这个invoke函数也就是retrofit里面invoke函数。所以,动态代理可以代理所有的接口,让所有的接口都走invoke函数,这样就可以拦截调用函数的执行,从而将网络接口的参数配置归一化。

五、网络请求过程

converter response2javaBean

六、设计模式

1)Retrofit 实例使用建造者模式通过Builder类构建。当构造函数的参数大于4个,且存在可选参数的时候既可以使用 建造者设计模式;

2)Retrofit 创建时的callFactory,使用工厂方法设计模式,但是似乎并不打算支持其他的工厂;

3)整个retrofit 采用的时外观模式。统一的调用创建网络请求接口实例和网络请求参数配置的方法;

4)Retrofit里面使用了动态代理来创建网络请求接口实例,这个是retrofit对用户使用来说最大的复用,其它的代码都是为了支撑这个动态代理给用户带来便捷性的;

动态代理和静态代理的区别?

静态代理类由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。

动态代理类是在程序运行期间由 JVM 根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。

静态代理:

静态代理业务类只需要关注业务逻辑本身,保证了业务类的重用性。代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,需要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任。如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法,增加了代码维护的复杂度。

动态代理:

动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler invoke)。这样,在接口方法数量比较多的时候,可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。而且动态代理的应用使类职责更加单一,复用性更强。

5)使用了策略模式对serviceMethod对象进行网络请求参数配置,即通过解析网络请求接口方法的参数、返回值和注解类型,从Retrofit对象中获取对应的网络的url地址、网络请求执行器、网络请求适配器和数据转换器;

6)ExecuteCallBack 使用装饰者模式来封装callbackExecutor,用于完成线程的切换;

7)ExecutorCallbackCall 使用静态代理(委托) 代理了Call进行网络请求,真正的网络请求由okhttpCall执行,然而okHttpCall不是自己执行,它是okhttp 提供call给 外界(retrofit)使用的唯一门户,其实这个地方就是门面模式;

8)ExecutorCallbackCall 的被初始化是在 ExecutorCallAdapterFactory里面通过适配器模式被创建的。CallAdapter采用了适配器模式 为创建访问Call接口提供服务。默认不添加Rxjava则使用默认的ExecutorCallAdapterFactory 将okhttp3.call转变成为 retroift中的call,如果有Rxjava则将okhttp3.call转化为abservable。

七、总结

Retrofit 通过 java 接口以及注解来描述网络请求,并用动态代理的方式生成网络请求的 request,然后通过 client 调用相应的网络框架(默认 okhttp)去发起网络请求,并将返回的 response 通过 converterFactorty 转换成相应的数据 model,最后通过 calladapter 转换成其他数据方式(如 rxjava Observable等)。

Retrofit 优点:

可以配置不同 HTTP client 来实现网络请求,如 okhttp、httpclient 等;

请求的方法参数注解都可以定制;

支持同步、异步和 RxJava;

超级解耦;

可以配置不同的反序列化工具来解析数据,如 json、xml 等;

框架使用了很多设计模式。

相关推荐
SRC_BLUE_1737 分钟前
SQLI LABS | Less-39 GET-Stacked Query Injection-Intiger Based
android·网络安全·adb·less
无尽的大道4 小时前
Android打包流程图
android
镭封5 小时前
android studio 配置过程
android·ide·android studio
夜雨星辰4875 小时前
Android Studio 学习——整体框架和概念
android·学习·android studio
邹阿涛涛涛涛涛涛6 小时前
月之暗面招 Android 开发,大家快来投简历呀
android·人工智能·aigc
IAM四十二6 小时前
Jetpack Compose State 你用对了吗?
android·android jetpack·composer
奶茶喵喵叫6 小时前
Android开发中的隐藏控件技巧
android
Winston Wood8 小时前
Android中Activity启动的模式
android
众乐认证8 小时前
Android Auto 不再用于旧手机
android·google·智能手机·android auto
三杯温开水8 小时前
新的服务器Centos7.6 安卓基础的环境配置(新服务器可直接粘贴使用配置)
android·运维·服务器