Retrofit允许各种第三方库来对返回的HTTP call进行操作。因此这就要求Retrofit给出一套机制来使得API 请求和现有的第三库进行无缝的链接。这个机制就是CallAdapter,它可以将返回的 http call进行处理,从而适应不同的操作。
callAdapter使用了工厂模式,所以它的代码结构简练而又复杂。
public interface CallAdapter<T> {
Type responseType();
<R> T adapt(Call<R> call);
abstract class Factory {
public abstract retrofit2.CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit);
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}
这是CallAdapter的源码。其中factory是工厂,在我们自定义自己的CallAdapter时需要继承实现factory,其中的get方法用于生产我们想要的CallAdapter。getParameterUpperBound的作用是返回第index个参数的最上层的类。getRawType的作用是返回参数的原始的类型。比如List
public final class GuavaCallAdapterFactory extends CallAdapter.Factory {
public static GuavaCallAdapterFactory create() {
return new GuavaCallAdapterFactory();
}
private GuavaCallAdapterFactory() {
doSomethins()
}
@Override
public CallAdapter<ListenableFuture<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
return new CallAdapter<ListenableFuture<?>>() {
@Override
public Type responseType() {
return responseType;
}
@Override
public <R> ListenableFuture<R> adapt( final Call<R> call)
{
doSomething()
}
}
};
}
}
这是一个简单的实现的结构。在adapt中我们可以对返回的call进行处理,将它封装成我们想要的格式,这里我想将它封装为ListenableFuture格式。
几种CallAdapter应用的例子
1. Retrofit在Android平台默认的例子
先举个例子,MainActivity上的操作。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
uerService repo = retrofit.create(uerService.class);
Call<List<Contributor>> call = repo.contributorsByAddConverterGetCall("square", "retrofit");
call.enqueue(new C