Retrofit2源码初探
Retrofit是Square面向安卓平台提供的http客户端开源网络库,官网上用一句话介绍:
A type-safe HTTP client for Android and Java
本文就Retrofit2源码进行探讨,粗略分析其运行原理。分析代码版本为2.0.3-SNAPSHOT,官网:Retrofit主页,github地址
Retrofit2框架一览
Retrofit2相比于Retrofit1.X的调用有些许不同,而且提供直接取消正在进行任务的接口。其调用如下:
interface PageService {
@GET Call<Page> get(@Url HttpUrl url);
}
public static void main(String... args) throws Exception {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectionPool(new ConnectionPool(100, 30, TimeUnit.SECONDS))
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(HttpUrl.parse("https://example.com/"))
.addConverterFactory(mConverterFactory)
.client(okHttpClient)
.build();
PageService pageService = retrofit.create(PageService.class);
//同步
pageService.get(HttpUrl.parse(args[0])).execute();
//异步
pageService.get(HttpUrl.parse(args[0])).enqueue(new Callback<Page>() {
....
});
}
Retrofit2依赖于Square自家的网络库OkHttp,OkHttp相当于网络请求中的传输层,Retrofit2在其上提供Http服务。retrofit2.Retrofit类是框架主要操作类,利用其设置参数,生成调用接口。在Retrofit2框架中需要关注以下几个类:
- Retrofit:框架主要操作类,提供网络参数设置接口
- ServiceMethod:将接口方法转换为http请求,框架的核心类
- OkHttpCall:实现Call接口,封装okhttp操作
- Converter.Factory:Converter转换器工厂
CallAdpter:将Call转换为T的适配器
Retrofit2代码相对简洁,缺乏繁琐的抽象接口定义,可读性稍差。以上几个类组成并实现了Retrofit2框架的主要功能。
retrofit2.Retrofit
Retrofit是框架主要操作类,使用Retrofit.Builder创建,Builder可以设置baseUrl,CallAdapterFactory,ConverterFactory,callbackExecutor等参数。Retrofit提供callFactory,requestBodyConverter,responseBodyConverter,callAdapter等方法获得运行时设置。
Builder初始化使用Platform.get获得当前平台信息,Platform是对运行平台的抽象,在Android平台,callback默认回调到主线程。
//Retrofit.Builder构造函数
public Builder() {
this(Platform.get());
}
Builder(Platform platform) {
this.platform = platform;
//设置默认converterFactory为BuiltInConverters
converterFactories.add(new BuiltInConverters());
}
Retrofit的create方法利用动态代理生成调用接口实例。create实现如下:
public <T> T create(final Class<T> service) {
.... //忽略代码
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, Object... args) throws Throwable {
//忽略Object自身方法
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//利用ServiceMethod将接口方法转换为ServiceMethod
ServiceMethod serviceMethod = loadServiceMethod(method);
//生成OkHttpCall对象,OkHttpCall是Call接口的实现类,封装okhttp库操作
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
//利用CallAdapter<T>将Call转换为T类型
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
create方法是Retrofit2框架的主要实现环节,在安卓平台下,默认callAdpter将OkHttpCall转换为ExecutorCallbackCall,即把Callback回调接口放到主线程运行。create利用ServiceMethod类对接口方法进行解析,并使用OkHttpCall封装Http请求过程,最后利用callAdpter完成线程转换或类型转换操作。
ServiceMethod
Retrofit2利用ServiceMethod将接口方法信息转换为http请求。ServiceMethod通过Builder创建,创建时对接口方法注解、方法参数注解进行解析。ServiceMethod提供toRequest,toResponse生成OkHttp的Request和Response。ServiceMethod对象创建过程如下:
ServiceMethod对象创建时对接口方法进行解析,在解析方法参数注解时生成ParameterHandler列表,ParameterHandler的不同类型对应不同的参数注解,子类重写apply方法,实现不同注解下http请求创建操作。
ServiceMethod的toRequest方法利用RequestBuilder创建Request类,RequestBuilder封装了创建过程的一系列操作。OkHttpCall对象初始化需要传入ServiceMethod引用,OkHttpCall对象在其内部调用ServiceMethod的toRequest方法生成Request,从而调用OkHttp库实现网络请求。
Converter.Factory
Converter代表内容转换类,Converter.Factory是其工厂类,Retrofit通过Converter.Factory类提供转换器。Converter.Factory定义如下:
abstract class Factory {
// Responsebody转换
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return null;
}
// Requestbody转换
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return null;
}
// 字符串转换,用@Field,@FieldMap,@Path等注解值转换
public Converter<?, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return null;
}
}
Retrofit类包含Converter.Factory列表,通过遍历获取合适的转换器工厂生成合适的转换器。Retrofit支持gson,jackson,moshi,protobuf,simplexml,wire等解析库,为了减少对其他类库的依赖,Retrofit把对解析库的支持放到子项目中,例如项目需要支持gson加上:
compile("com.squareup.retrofit2:retrofit-converters:2.0.3-SNAPSHOT")
Retrofit默认提供BuiltInConverters生成转换器,默认的转换器对内容基本不作修改返回。
CallAdpter
Retrofit通过CallAdpter支持guava,java8,rxjava的事件驱动模型。同样,为了减少依赖,Retrofit把这部分代码放在独立子项目中,使用时添加类库依赖即可。
在Android平台下,默认CallAdapterFactory为ExecutorCallAdapterFactory,重写get方法返回匿名adpter,将传入的Call转换为ExecutorCallbackCall,即把callback回调到主线程。
总结
Retrofit2封装Okhttp网络库,提供http客户端服务,框架支持丰富的方法注解和参数注解,使用方便。同时支持gson,jackson,rxjava等第三方开源库。