前言
本节将介绍如何自定一个CallAdapter,通过源码的级别讲解Retrofit2的CallAdapter。
先看一下CallAdapter接口定义及各方法的作用,已上注释:
public interface CallAdapter<R, T> {
//返回此适配器将HTTP响应正文转换为Java时使用的值类型对象。 例如, Call <Repo>的响应类型是Repo。 这个类型用于准备传递给adapt的call。
Type responseType();
//这个方法很重要,会在 Retrofit的create(final Class<T> service)方法中被调用,并把okHttpCall即Call传进来serviceMethod.callAdapter.adapt(okHttpCall),接下来我们可以对Call进行操作了
T adapt(Call<R> call);
//CallAdapter工厂,retrofit默认的DefaultCallAdapterFactory其中不对Call做处理,是直接返回Call。
abstract class Factory {
// 在这个方法中判断是否是我们支持的类型,returnType 即Call<Requestbody>和`Observable<Requestbody>`
// RxJavaCallAdapterFactory 就是判断returnType是不是Observable<?> 类型
// 不支持时返回null
//返回值必须是Custom并且带有泛型(参数类型),根据APIService接口中的方法返回值,确定returnType,如: CustomCall<String> getCategories();,那确定returnType就是CustomCall<String>
public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
Retrofit retrofit);
// 用于获取泛型的参数 如 Call<Requestbody> 中 Requestbody
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}
// 用于获取泛型的原始类型 如 Call<Requestbody> 中的 Call
// 如Call<Requestbody>拿到的原始类型就是Call
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}
看看Retrofit默认使用的DefaultCallAdapterFactory,默认不做处理直接返回Call:
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
static final CallAdapter.Factory INSTANCE = new DefaultCallAdapterFactory();
//重要的方法,注意看哥们
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
//判断APIService接口方法的返回值,是否为Call,如果返回值不是Call,那么不做处理,返回null就是不处理。
if (getRawType(returnType) != Call.class) {
return null;
}
//这里和我们在上面的介绍是一样的,底层也是调用了getParameterUpperBound(0, (ParameterizedType) returnType)方法,获取泛型的参数,即返回值类型,以便后期Converter做转换操作,
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
//直接返回Call
@Override public Call<Object> adapt(Call<Object> call) {
return call;
}
};
}
}
没有demo说再多也没用,下面来自定义一个叫CustomCallAdapter:
-
第一步定义CustomCall,专门处理Call的数据
public static class CustomCall<R> { public final Call<R> call; public CustomCall(Call<R> call) { this.call = call; } public R get() throws IOException { return call.execute().body(); } }
-
第二步定义CustomCallAdapter实现 Call<T> 到 CustomCall<T>的转换,这里需要注意的是最后的泛型,是我们要返回的类型:
public class CustomCallAdapter implements CallAdapter<R, CustomCall<R>> { private final Type responseType; public CustomCallAdapter(Type responseType) { this.responseType = responseType; } /** * 真正数据的类型,如Call<T> 中的 T,这个T会作为 Converter.Factory.responseConverter的第一个参数 * * @return */ @Override public Type responseType() { return responseType; } @Override public CustomCall<R> adapt(Call<R> call) { return new CustomCall<>(call); } }
-
第三部提供一个CustomCallAdapterFactory用于向Retrofit提供CustomCallAdapter:
public class CustomCallAdapterFactory extends CallAdapter.Factory { public static CustomCallAdapterFactory create() { return new CustomCallAdapterFactory(); } @Nullable @Override public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) { //获取原始类型 Class<?> rawType = getRawType(returnType); //返回值必须是Custom并且带有泛型(参数类型),根据APIService接口中的方法返回值,确定returnType //如 CustomCall<String> getCategories();,那确定returnType就是CustomCall<String> if (rawType == CustomCall.class && returnType instanceof ParameterizedType) { Type callReturnType = getParameterUpperBound(0, (ParameterizedType) returnType); return new CustomCallAdapter(callReturnType); } return null; } }
第四步使用addCallAdapterFactory向Retrofit注册CustomCallAdapterFactory
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(GitHubService.GLABALURL)
.addCallAdapterFactory(CustomCallAdapterFactory.create())
.addConverterFactory(StringConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build();
注: addCallAdapterFactory与addConverterFactory同理,也有先后顺序。
最后来看看retrofit执行流程:
create(final Class<T> service)---> loadServiceMethod(method)---->
ServiceMethod.Builder..build()--->createCallAdapter()--->
method.getGenericReturnType()--->callAdapter(returnType, annotations)--->
nextCallAdapter(null, returnType, annotations)--->
createResponseConverter()--->method.getAnnotations()--->
etrofit.responseBodyConverter(responseType, annotations)--->
nextResponseBodyConverter(null, type, annotations)
上面的是retrofit的执行流程,按照上面的步骤可以查看所有的源代码。
本节就到这里,下一节将会讲解,Converter 的自定义。可能文中会有疏漏或错误,敬请指正,谢谢大家!