Retrofit源码浅析

      Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现的。Retrofit: 通过注解,把一个Java接口转化成一个http 请求,底层网络请求基于okhttp。本文介绍是基于Retrofit2.0源码浅析。

      从Retrofit源码结构可以看出,Retrofit 源码分成两部分 

一部分是包retrofit2.http里面的,在Java接口方法中使用,用来控制http行为的注解。

一部分是retrofit2里面的,负责把REST API转化成Java接口。

Retrofit和okhttp的关系

retrofit依赖okhttp库,retrofit 所有的网络请求都是由okhttp处理,可以说retrofit是对okhttp封装了,让其使用更加简单方便。 
okhttp 准确来说是一个Java库,没有Android中主线程和工作线程的概念。

Android有两个限制,第一不能再主线程中直接请求网络,第二不能在工作线程中直接更新UI,所以,如果我们在Android中直接使用okhttp,需要用到Handler来传递请求结果。而如果使用retrofit,则不需要我们去创建线程执行网络请求,也不需要使用Handler把请求结果从工作线程传递到主线程。retrofit直接在主线程中发起异步请求,最后收到请求结果也是在主线程中,非常方便。

主要类和方法

Retrofit:retrofit框架的入口类,主要有两个功能: 
1、通过内部类Builder配置构建Retrofit实例。Builder主要配置选项:

1. client(OkHttpClient client) :设置一个配置好的OkHttpClient实例,不配置的话retrofit会默认new一个。
2. baseUrl(String baseUrl) :设置API地址。
3. addConverterFactory(Converter.Factory factory) :设置一个数据转化工厂,比如把Json和实体类之间的转化。
4. addCallAdapterFactory(CallAdapter.Factory factory):设置一个适配器工厂,方便和其他库配合使用,如RxJava。

 如果我们没有设置执行任务的线程池的话,Retrofit会根据不同的平台,得到默认的线程池。

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (callbackExecutor == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { callbackExecutor = platform.defaultCallbackExecutor(); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

        Retrofit首先创建一个在主线程中的Handler,然后默认线程池执行的任务都是在Android的主线程中执行的,这也是在Retrofit异步回调中我们能直接在里面更新UI的原因。

      另外,Retrofit根据不同使用平台,会默认添加一个CallAdapterFactory,安卓中,添加的是ExecutorCallAdapterFactory:通过Retrofit的create方法,实现描述http请求的Java接口。

        使用Retrofit时,首先要通过Retrofit实例来得到一个请求接口的实例(github),然后调用这个实例的一个方法(contributors)构造一个Call对象。这个过程主要是Retrofit的create方法实现的。

      当调用接口里面方法的时候(github.contributors(“square”, “retrofit”) ),会执行InvocationHandler里面的内容,通过反射,得到调用的method相关信息,然后构造ServiceMethod和OkHttpCall的实例,在Android中通过ExecutorCallAdapterFactory 把 OkHttpCall 进行转换 ExecutorCallbackCall:

     最后我们得到的Call对象实际上是ExecutorCallbackCall实例。得到Call实例之后,就可以通过call.enqueue进行网络请求。

       在ExecutorCallbackCall中的enqueue里面,又调用delegate.enqueue方法,这个delegate,其实是OkHttpCall对象,也就是调用OkHttpCall中的enqueue方法。 
     通过ServiceMethod的toRequest方法得到的,构造一个okhttp中的Request对象。其中构造RequestBuilder的参数都是ServiceMethod 从Java接口中的注解解析出来的。

       ServiceMethod: 从这个类的方法结构可以看出,这个类主要作用是把方法的注解解析成变量保存起来。

猜你喜欢

转载自my.oschina.net/u/3761887/blog/1615115