Retrofit做为时下android里比较经常使用的库,特别是结合着rxjava 后用起来非常酸爽啊,本篇就是剖析一下retrofit2.0结合adapter-rxjava,converter-gson后整个流程是怎样串起来的,以及源码的解析java
retrofit源码地址 图一就是今天的重点了,图二是发起请求对应的注解种类了 android
都知道retrofit实际调用的是okhttp。也能够说retrofi就是在okhttp的基础上包了一层,经过大量的设计模式进行功能模块的解耦,使得整个整个流程变得整洁和清爽、git
阅读一个三方库 先从接口入手,先了解一下上层大体提供了哪些功能有助于快速理解github
**Call **设计模式
对于okhttp 的call的的一个再包装,也是真正发出请求的对象接口
public interface Call<T> extends Cloneable {
Response<T> execute() throws IOException;
void enqueue(Callback<T> callback);
boolean isExecuted();
void cancel();
Call<T> clone();
/**返回的是okhttp的Request. */
Request request();
}
复制代码
**CallAdapter **api
//能够把Call对象转化为另一个对象,如Observable,Flowable
public interface CallAdapter<R, T> {
//Type 返回值泛型的对象类型如:Flowable<Response<Bean>>里的Response<Bean>
Type responseType();
//传入一个R返回一个T,T:返回值 一个Call或者Flowable
T adapt(Call<R> call);
//工厂里提供三个方法 1:根据返回值returnType获取具体请求的CallAdapter 2:根据返回值type 获取泛型里的数据类型
// 3:经过type获取class的类型,获取整个返回值的类型 如Observable<T>,Flowable<T> ,Call<T>
// 2,3 均为工具类
abstract class Factory {
//abstract抽象方法,必定要被实现
public abstract @Nullable 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);
}
}
}
**Callback **
请求回调
**Converter **
数据转换适配器,能够对请求的数据或者响应的数据再度处理
public interface Converter<F, T> {
T convert(F value) throws IOException;
/** Creates {@link Converter} instances based on a type and target usage. */
abstract class Factory {
/**
* 传入ResponseBody返回t,对响应数据进行解析,converter-gson会重写此方法
*/
public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
Annotation[] annotations, Retrofit retrofit) {
return null;
}
/**
*
*传入T返回ResponseBody 对请求数据进行处理,只有在 申明@Body, @Part ,@PartMap
*这三个注解时才会生效
*
*/
public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return null;
}
/** *
* {@link Field @Field}, {@link FieldMap @FieldMap} values,
* {@link Header @Header}, {@link HeaderMap @HeaderMap}, {@link Path @Path},
* {@link Query @Query}, and {@link QueryMap @QueryMap} values.
对以上注解的值进行处理 而已已经被BuiltInConverters(默认解析类)类重写,外部重写无效
*/
public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return null;
}
/**
工具类做用与CallAdapter里的同样
*/
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}
复制代码
获取 retrofit 实例以及添加上rxjava 请求适配器和converter-gson解析器
public Retrofit getRetrofit(String baseurl, OkHttpClient client) {
if (client == null)
client = getOkHttpClient();
Retrofit.Builder builder = new Retrofit.Builder();
builder.baseUrl(baseurl);//baseurl路径
builder.client(client)//添加客户端
.addConverterFactory(GsonConverterFactory.create());//添加Gson格式化工厂
//添加 rxjava
builder.addCallAdapterFactory(RxJava2CallAdapterFactory
.createWithScheduler(Schedulers.from(AppExecutor.instance())));
retrofit = builder.build();
return retrofit;
}
//自定义的通用解析类,t为data内具体对象,msg和code为公用数据部分
public class Response<T> {
private T data;
private String msg;
private String code;
}
//定义接口类
public interface ApiService {
/**
* 测试数据
*/
@GET("data/福利/{num}/{page}")
Flowable<Response<Bean>> getGirlList(@Path("num") int num, @Path("page") int page);
}
//获取ApiService
ApiService apiservice=getRetrofit(baseurl,OkHttpClient).create(serviceClass)
//发起请求,(这里未经封装,正常使用要再封装下)
apiservice.getGirlList(1,2).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribeWith(new ResourceSubscriber<Response<Bean>>() {
@Override
public void onNext(Response<Bean> o) {
//结果回调
}
@Override
public void onError(Throwable t) {
}
@Override
public void onComplete() {
}
})
复制代码
Retrofit实例是使用建造者模式经过Builder类进行建立的数组
核心类
这里只关心Android平台下的java8的不看
static class Android extends Platform {
// Guarded by API check.
@Override
boolean isDefaultMethod(Method method) {
if (Build.VERSION.SDK_INT < 24) {
return false;
}
return method.isDefault();
}
@Override
public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
/**
* ExecutorCallAdapterFactory默认工厂类,
* if (getRawType(returnType) != Call.class) {
* return null;}
*只解析返回类型为Call.class的数据,即原生retrofit的返回值都会使用这个工厂,缘由后面
*/
@Override
List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
return singletonList(new ExecutorCallAdapterFactory(callbackExecutor));
}
/**
* android平台 默认为MainThreadExecutor,
*/
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
handler.post(r);
}
}
}
**默认CallAdapter实体类 提供了只解析解析返回Call.class类型的CallAdapter **
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
//android平台下 默认为MainThreadExecutor,数据切换到主线程,okhttp默认是在子线程
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
// 默认为 ExecutorCallAdapterFactory,只解析返回类型为Call.class的数据,即原生retrofit的返回值
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
converterFactories.add(new BuiltInConverters());//默认数据解析类
当返回类型为ResponseBody时适用(即:原生okhttp)
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());;//defaultConverterFactories实际上什么也没有,默认的解析行为都在BuiltInConverters类
//unmodifiableList() :返回一个只能被访问不能被修改的集合
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
复制代码
而后看下 GsonConverterFactory gson解析类 重写了responseBodyConverter和requestBodyConverter 实际都经过 gson 把返回数据或者请求数据解析成指定的type缓存
public final class GsonConverterFactory extends Converter.Factory {
/**
* Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and
* decoding from JSON (when no charset is specified by a header) will use UTF-8.
*/
public static GsonConverterFactory create() {
return create(new Gson());
}
/**
* Create an instance using {@code gson} for conversion. Encoding to JSON and
* decoding from JSON (when no charset is specified by a header) will use UTF-8.
*/
public static GsonConverterFactory create(Gson gson) {
return new GsonConverterFactory(gson);
}
private final Gson gson;
private GsonConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
this.gson = gson;
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
}
复制代码
**而后看下 RxJava2CallAdapterFactory rxjava适配器 实现get方法 只解析 返回类型为 Observable.class ,isFlowable , isSingle ,isMaybe四类bash
public final class RxJava2CallAdapterFactory extends CallAdapter.Factory {
/**
* Returns an instance which creates synchronous observables that do not operate on any scheduler
* by default.
*/
public static RxJava2CallAdapterFactory create() {
return new RxJava2CallAdapterFactory(null, false);
}
/**
* Returns an instance which creates asynchronous observables. Applying
* {@link Observable#subscribeOn} has no effect on stream types created by this factory.
*/
public static RxJava2CallAdapterFactory createAsync() {
return new RxJava2CallAdapterFactory(null, true);
}
/**
* Returns an instance which creates synchronous observables that
* {@linkplain Observable#subscribeOn(Scheduler) subscribe on} {@code scheduler} by default.
*/
public static RxJava2CallAdapterFactory createWithScheduler(Scheduler scheduler) {
if (scheduler == null) throw new NullPointerException("scheduler == null");
return new RxJava2CallAdapterFactory(scheduler, false);
}
private final Scheduler scheduler;
private final boolean isAsync;
private RxJava2CallAdapterFactory(Scheduler scheduler, boolean isAsync) {
this.scheduler = scheduler;
this.isAsync = isAsync;
}
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
if (rawType == Completable.class) {
// Completable is not parameterized (which is what the rest of this method deals with) so it
// can only be created with a single configuration.
return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false,
false, true);
}
boolean isFlowable = rawType == Flowable.class;
boolean isSingle = rawType == Single.class;
boolean isMaybe = rawType == Maybe.class;
if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
return null;
}
boolean isResult = false;
boolean isBody = false;
Type responseType;
if (!(returnType instanceof ParameterizedType)) {
String name = isFlowable ? "Flowable"
: isSingle ? "Single"
: isMaybe ? "Maybe" : "Observable";
throw new IllegalStateException(name + " return type must be parameterized"
+ " as " + name + "<Foo> or " + name + "<? extends Foo>");
}
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Class<?> rawObservableType = getRawType(observableType);
if (rawObservableType == Response.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Response must be parameterized"
+ " as Response<Foo> or Response<? extends Foo>");
}
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
} else if (rawObservableType == Result.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Result must be parameterized"
+ " as Result<Foo> or Result<? extends Foo>");
}
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
isResult = true;
} else {
responseType = observableType;
isBody = true;
}
return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
isSingle, isMaybe, false);
}
}
复制代码
**继续 Retrofit 类核心方法 **async
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);//service必须为接口类,且方法数>0
if (validateEagerly) {//validateEagerly 是否预解析service里全部方法注解,正常是使用一个方法才解析一个,而后放到缓存里,下次直接用缓存
eagerlyValidateMethods(service);
}
//动态代理,传入一个接口返回一个对象
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service},
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override
public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//platform.isDefaultMethod(method) 平台下 痕为fasle,兼容java8的不关心
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
终于到重点 loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
复制代码
**先看 loadServiceMethod(method) **
核心方法 result = ServiceMethod.parseAnnotations(this, method);
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(method,
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
先看一下RequestFactory 类 经过解析注解 提供 okhttp3.Request(真正的请求)
final class RequestFactory {
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
private final Method method; // 调用的service内方法名字
private final HttpUrl baseUrl;
final String httpMethod; // 请求方法:get.post.put...
private final String relativeUrl;//实际的url: baseUrl+ 后缀默认
private final Headers headers;// 头信息
private final MediaType contentType;//contentType
private final boolean hasBody;// post方式才有
private final boolean isFormEncoded;//是不是表单提交
private final boolean isMultipart;//带文件的键值对提交
private final ParameterHandler<?>[] parameterHandlers;//这个类很重要,负责根据不一样的注解类型 去把传入的参数和注解的value 作相应的拼接处理
//retrofit里关于注解的解析 都在Builder 里
static final class Builder {
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();//获取方法上的注解
this.parameterTypes = method.getGenericParameterTypes();//传入参数对应的类型
this.parameterAnnotationsArray = method.getParameterAnnotations();//参数注解,二维数组,每一个参数上的注解都是数组
}
RequestFactory build() {
for (Annotation annotation : methodAnnotations) {
//确认请求方式 并对传入注解的value作校验,根据请求方式肯定这次请求是否有body
parseMethodAnnotation(annotation);
}
//这里开始解析方法上的注解参数,能够有多个参数而后 每一个参数上能够跟多个注解,全部是个二维数组,说是这样说,可是实际操做的时候 一个参数上只容许跟一个注解,多了会包错
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p]);
}
return new RequestFactory(this);
}
}
}
复制代码
**看下 parseParameter() **
/**
* 解析参数注解
*
* @param p 当前参数的位置
* @param parameterType 参数对应的类型
* @param annotations 参数对应的注解,retrofit只容许有一个
* @return
*/
private ParameterHandler<?> parseParameter(
int p, Type parameterType, @Nullable Annotation[] annotations) {
ParameterHandler<?> result = null;
if (annotations != null) {
for (Annotation annotation : annotations) {
ParameterHandler<?> annotationAction =
parseParameterAnnotation(p, parameterType, annotations, annotation);
if (annotationAction == null) {
continue;
}
//一个参数上只容许跟一个注解 多了会抛异常
if (result != null) {
throw parameterError(method, p,
"Multiple Retrofit annotations found, only one allowed.");
}
result = annotationAction;
}
}
if (result == null) {
throw parameterError(method, p, "No Retrofit annotation found.");
}
return result;
}
复制代码
再看 parseParameterAnnotation()