Retrofit源码解析

Retrofit是Android端网络请求框架,支持标准的HTTP协议。简单易用,代码量少。比较有意思的是Retrofit主要原理是动态代理和反射,感觉这种想法比较新颖。本文分析的版本是Retrofit1.9.0(2.0.+有挺多变化的)。
阅读之前请了解Java动态代理。推荐Java动态代理

1 Retrofit特点

(1)支持数据反序列化和反序列化借口配置。
(2)支持网络数据接口自定义配置。

2 类分析

2.1 RestAdapter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//方法解析信息Map,保存每个方法的信息避免每一次都需要解析方法,节省时间。
private final Map<Class<?>, Map<Method, RestMethodInfo>> serviceMethodInfoCache =
new LinkedHashMap<Class<?>, Map<Method, RestMethodInfo>>();
//保存请求接口的url
final Endpoint server;
//网络数据交互Executor
final Executor httpExecutor;
//完成数据回调Executor
final Executor callbackExecutor;
//请求拦截处理
final RequestInterceptor requestInterceptor;
//数据序列化和反序列化工具
final Converter converter;
final Log log;
final ErrorHandler errorHandler;

//网络请求Provider
private final Client.Provider clientProvider;
private final Profiler profiler;
//这个是联合RxJava使用
private RxSupport rxSupport;

通过接口创建代理对象

1
2
3
4
5
public <T> T create(Class<T> service) {
Utils.validateServiceClass(service);
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new RestHandler(getMethodInfoCache(service)));
}

2.2 RestHandler.java

1
2
3
4
5
6
7
//在这个方法内解析方法、根据方法走不同的请求方式。
//分为三种模式:返回值类型是自定义Bean类型;返回类型是void,需要处理回调;还有一种是RxJava(暂不了解-_-)
public Object invoke(Object proxy, Method method, final Object[] args)

//请求网络数据,反序列数据
private Object invokeRequest(RequestInterceptor requestInterceptor, RestMethodInfo methodInfo,
Object[] args)

2.3 RestMethodInfo.java

记录每个方法的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//返回值类型
final ResponseType responseType;
final boolean isSynchronous; //是有返回值类型
final boolean isObservable; //是RxJava中的Observable类型
Type responseObjectType;
RequestType requestType = RequestType.SIMPLE;
String requestMethod;
boolean requestHasBody;
String requestUrl; //请求接口的uri
Set<String> requestUrlParamNames;
String requestQuery;
List<retrofit.client.Header> headers;
String contentTypeHeader;
boolean isStreaming;

1
2
//解析方法信息
private void parseMethodAnnotations()

2.4 Converter.java

1
2
3
4
5
//网络数据反序列化
Object fromBody(TypedInput body, Type type) throws ConversionException;

//请求数据格式化
TypedOutput toBody(Object object);

2.5 Request.java

1
2
3
4
5
private final String method;
private final String url;
private final List<Header> headers;
//请求参数body
private final TypedOutput body;

3 比较Volley

Volley解析网络框架比较
相同点:
(1)都支持标准的HTTP协议。
不同点
(1)Volley内置支持图片加载;Retrofit不支持。
(2)Volley对多种HTTP返回码进行处理;Retrofit也处理了基本的的返回码,但没有Volldey详细。
(3)Volly中Request自定义设置重试机制;Retrofit不支持。
(4)Volley不支持大数据文件请求;Retrofit支持。
(5)Volley内置支持数据缓存和304返回码处理;Retrofit默认不支持缓存,但可以搭配okhttp实现数据缓存和304返回码处理。