Android Retrofit 原理解析
一.基本使用
先来简单看一下基本的使用方法。
一些基本注解和使用可以参照这篇文章。
//请求接口
public interface RequestService {
@GET("path")//注解表明为get请求,值为相对url
Call<DataModel> getData(@Query("key1") String value, @Query("key2") String value2);//请求的方法,参数代表一个一个的param配置(注解为key,值为value)
//返回值Call<DataModel>为retrofit自带的返回值类型,下面会细说,返回值用于发起请求等后续工作
}
//构建retrofit对象,设置一些配置项
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://baseUrl/")//baseUrl
.addConverterFactory(GsonConverterFactory.create())//设置请求参数和请求结果的数据转换,通常我们可以使用retrofit提供的Gson解析
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//设置返回类型的解析器,retrofit默认提供的是一个Call对象,可以直接发起请求,我们也可以使用其提供的RXJava的解析器,使其可以返回Observable对象进行链式调用请求,下面会细说
.build();//builder模式构建
RequestService requestService = retrofit.create(RequestService.class);//通过retrofit的动态代理,创建请求接口对象
Call<DataModel> call = requestService.getData("v1","v2");//调用请求的代理对象的相应方法,传入参数,生成Call对象
call.enqueue(new Callback<DataModel>() {
//使用Call对象enqueue发起异步请求,并设置回调
@Override
public void onResponse(Call<DataModel> call, Response<DataModel> response) {
//请求成功
DataModel model = response.body();
//success
}
@Override
public void onFailure(Call<BookSearchModel> call, Throwable t) {
//请求失败
//failed
}
});
call.cancel();//取消掉请求:回调不会再调用,socket连接被终止
二.源码分析
1.Retrofit.Builder构建参数
创建请求需要一个Retrofit对象,我们也可以为每个请求有不同的配置,这个对象里面可以配置几个配置项,创建时使用的是builder模式
public Retrofit build() {
if (baseUrl == null) {
//baseUrl
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
//CallFactory
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
//CallbackExecutor
callbackExecutor = platform.defaultCallbackExecutor();
}
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));//CallAdapterFactory
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);//ConverterFactory
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);//build
}
}
由代码可知,创建retrofit对象使用的是builder模式,可以配置几个东西,baseUrl就是请求的基本url(在每个请求中也可配置整个url);其余的几个下面来单独说
2.可配置项
(1)CallFactory
CallFactory是请求所用的客户端,默认为OkHttpClient,我们也可以设置自己的OkHttpClient对象作为请求客户端
(2)ConverterFactory
请求的参数以及请求回来的数据,都需要转换,比如某个序列化和反序列化某个model,这就需要提供用于转换数据的东西,retrofit提供了ConverterFactory的类,通过工厂模式构建出Converter,提供将request和response转换的方法
public interface Converter<F, T> {
T convert(F value) throws IOException;//F转换为T
abstract class Factory {
//工厂模式
//提供将ResponseBody转换的Converter
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return null;
}
//提供将params转换为RequestBody的Converter
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return null;
}
}
}
//retrofit提供的用gson转换的ConverterFactory
public final class GsonConverterFactory extends Converter.Factory {
...
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
...
}
//retrofit提供的用gson转换ResponseBody的Converter
final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
...
@Override public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
return adapter.read(jsonReader);
}
}
可以看到Gson的转换器就是使用Gson来解析数据的,同理我们可以实现自己的ConverterFactory构建不同的Converter,比如Jackson、fastjson等等
(3)CallAdapterFactory
刚刚我们说过,当我们调用一个接口的方法时,其返回值是用于发起请求等后续操作的Call对象,这是retrofit默认提供的一个包装了OkHttp请求的Call对象,可以方便的发起请求;
当我们想使用RXJava时怎么办?retrofit为我们提供了CallAdapterFactory,也是利用工厂模式生成CallAdapter对象,这个CallAdapter对象,就是用于将原始的OkHttpCall对象包装成我们想要的返回类型(retorfit使用的是okHttp,其创建的请求对象是OkHttpCall对象);
默认的,retrofit提供的是Call对象的CallAdapter:
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;//实际的OkHttpCall对象
}
@Override public void enqueue(final Callback<T> callback) {
delegate.enqueue(new Callback<T>() {
//异步发起请求