从 ServiceMethod角度来认识retrofit框架

对于Android开发者而言,retrofit可以说算是比较实用的网络请求框架,而且是开源的。那么,从请求执行的角度,以 interface 中我们定义的方法为起始,解读 retrofit 的执行流程。目的是想让我们对 retrofit 的执行流程有一个框架性的了解,同时也是为了面试的时候,可以跟面试官“有的聊”。

ServiceMethod是什么?retrofit的核心思想是将 http 请求过程抽象成了一个对象 ServiceMethod。 这个对象的构造的时候,会通过 java 反射的方式传入一个 method 对象,而这个对象就是我们在 interface 中定义的请求方法。通过对 method 对象 find usage ,我们可以发现,一共有两处使用了这个 method 对象。

可以看到,里面使用了 method 对象的两个关键信息:注解和返回类型。而其中涉及的两个方法则同时出现在了 ServiceMethod.build() 中。

public ServiceMethod build() {

callAdapter = createCallAdapter();

responseConverter = createResponseConverter();

}

通过 method 的 returnType 构造出 createCallAdapter 和 responseConverter,然后自动的完成从服务器的返回结果,到程序用的 model 类实例的转换。通过 annotation 定义网络请求相关的参数。annotation 的解析是一个简单但繁琐的工作,需要对每一个注解逐个判断。因此我们把重点放在 callAdapter 和 responseConverter 的分析上。而我在阅读相关代码的过程中,发现其中的泛型部分对我们理解整个框架造成了很大的阻碍。因此,想理解 retrofit,必须要弄懂其各个泛型类的意义,不然看一看就自己把自己绕晕了。

从 ServiceMethod角度来认识retrofit框架

其中,getAlbums() 就是我们的 method 方法。根据这个 method 方法, 生成 ServiceMethod 对象,返回的结果是 serviceMethod.callAdapter.adapt(okHttpCall); 。而我们知道,我们在 interface 中定义的 getAlbums() 的返回类型恰好是 RadioCall,两个类型就这么对上了。

在radioCall.execute() 的内部,我们会把调用 delegates.execute() 来实际执行网络请求。这个 delegates 的类型就是 retrofit.OkHttpCall。然后,发起请求,等待服务器返回结果,并对结果进行处理。尚学堂•百战程序员陈老师指出,此时的结果还是 rawResponse,即都是 json 字符串,还不是可以直接使用的 java model 对象。这个时候,我们就需要 responseConverter 来帮我们进行转换了。

正如我们上文所说,RadioCall 一般会把一个 okHttpCall 作为构造函数的参数,然后把实际请求委托给 okHttpCall,然后再 onResposne 回调中就能得到上面代码中的 Response,将我们的类带入,就是 Response。而这个,就是 execute() 的执行结果。然后我们就可以得到 Response 中的 model 对象了。

至此,retrofit 的请求执行流程就分析完毕。最后我们再从宏观的角度,从面试的角度,来阐述一下整个执行过程。

首先我们通过我们 create 出来的 retrofit 实例来调用接口方法。所有的 interface 方法都会在 java 动态代理机制的作用下,调用一个匿名类 new InvocationHandler 中的 invoke。在 invoke 中,会根据我们想调用的方法 method 构造出一个 serviceMethod,然后调用 serviceMethod.callAdapter.adapt(okHttpCall) 作为返回结果。

构造 serviceMethod 的时候,会根据 interface 中 method 的的返回类型,构造出 converter 和 callAdapter。其中, converter 一般使用 gson converter。gson converter 可以自动将服务器返回的 json 数据转化成 java 中的 model 类的实例。callAdapter 绝大多数的实现方式是在构造函数中接收一个 okHttpCall 实例,然后将 enqueue 和 execute 委托给这个 okHttpCall 实例来执行。okHttpCall 在获取到服务器数据之后,会利用 serviceMethod.toResponse(body) 来对数据进行转化。其中,转化的时候便利用了 converter。数据转化完成后,封装成 Response ,传递给调用方。其中 R 就是我们的数据类。


分享到:


相關文章: