最近找实习,经常被问到Retrofit的问题,答得也是磕磕绊绊。在这里记录一下,有不对的欢迎指正。
本文使用的Retrofit版本为2.3.0,RxJava为2.1.1。
基本使用(以配合RxJava为例)
- 创建Api接口
public interface NetApi {
@GET("/wcxdhr")
Observable<ResponseBody> getSomething(@Query("token") String token);
}
- 创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://github.com/")
//指定请求的callFactory为OkHttp3,这一步其实不必要,默认就是这个,如果要给OkHttpClient指定一些参数可以在这里传入
.client(new OkHttpClient())
//给serviceMethod添加返回类型(支持RxJava的Observable
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//Gson做数据转换,将服务器返回的数据转换成T类型
.addConverterFactory(GsonConverterFactory.create())
.build();
- 获得接口实例并调用相应方法,完成网络请求
retrofit.create(NetApi.class).getSomething(token)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ResponseBody>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(ResponseBody responseBody) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
源码解析
由于第一步较简单,因此主要以Retrofit的创建以及网络请求部分来做解析。
创建Retrofit对象
接下来我们将代码拆开一行行来看
第一行
Retrofit retrofit = new Retrofit.Builder()
Retrofit对象的创建,使用了建造者模式,我们点进源码来看看。
Builder(Platform platform) {
this.platform = platform;
}
public Builder() {
this(Platform.get());
}
可以看到Builder方法又做了一层封装,调用了另外一个Builder(Platform platform)方法,对Platform做了初始化。
Platform.get()方法就不展开讲了,主要是判断当前平台是Android还是Java8并返回相应的Platform对象。
第二行
.baseUrl("https://github.com/")
这一行会为Builder对象设置baseurl并返回Builder。
之后的三四五行类似,就不再赘述了。
第六行
.build();
看一下源码
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) {
callbackExecutor = platform.defaultCallbackExecutor();
}
//第二部分
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
//第三部分
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
将这段源码分为三部分,由代码可以看出
第一部分:判断baseurl、callFactory、callbackExecutor是否已指定并做一些初始化操作
第二部分:初始化callAdapterFactories列表以及converterFactories列表
第三部分:这里可以看出根据建造者模式,调用了Retrofit的构造函数,传入一二部分的参数,真正创建了Retrofit对象。
总结
总结一下,就是使用建造者模式,初始化并配置了一系列参数,创建了Retrofit对象。
进行网络请求
这一部分比较复杂,分为请求接口实例的创建、方法调用、及之后的RxJava部分
请求接口实例的创建
retrofit.create(NetApi.class)//这里会返回一个NetApi类的对象
看一下源码
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
//这里可以看到,是通过动态代理的方法拿到传入的service实例(jdk的代理是利用反射生成代理类 Proxyxx.class 代理类字节码,并生成对象)
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, @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);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//前面不用看,直接会调用到这三行
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
关于动态代理,不懂的可以看看这篇文章:java的动态代理机制详解
这里用动态代理的方法,生成网络请求接口的代理类,并返回动态代理。之后使用代理对象的方法时,会转交给InvocationHandler的invoke方法来调用。
方法调用
invoke方法的参数意义如下
/***** @param proxy 动态代理实例
* @param method 真正调用的方法的Method对象
* @param args 该方法的参数,可以为空,基本数据类型对应传入包装类
**/
public Object invoke(Object proxy, Method method, Object[] args)
接下来再进入invoke方法的实现,看最后三行,
第一行
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
首先看一下ServiceMethod的注释:翻译一下也就是将接口方法的调用转换为为HTTP调用
/** Adapts an invocation of an interface method into an HTTP call. */
进入loadServiceMethod(method)方法看一下
ServiceMethod<?, ?> loadServiceMethod(Method method) {
//这两行会查看该method是否有缓存,有的话直接取出,serviceMethodCache是一个ConcurrentHashMap
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
//接下来加锁,拿到该method的ServiceMethod
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
loadServiceMethod方法中逻辑非常清楚,就是先看是否有缓存,有的话取出,没有的话通过建造者模式创建result,缓存后返回。
接下来看一下ServiceMethod的创建过程
public ServiceMethod build() {
//创建CallAdapter、responseConverter
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
//...省略检查代码
responseConverter = createResponseConverter();
//解析请求方法注解(GET/POST/DELETE等等
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
//...省略检查代码
//parameterAnnotationsArray在Builder的构造函数中初始化
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
if (Utils.hasUnresolvableType(parameterType)) {
throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
parameterType);
}
//解析该方法的参数注解
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
if (parameterAnnotations == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
//...省略检查代码
//返回ServiceMethod,在构造方法中会对各种参数进行初始化(使用传入的this即builder的参数)
return new ServiceMethod<>(this);
}
总结一下,这一行就是拿到ServiceMethod,查看有无缓存,无缓存则创建。
第二行
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
看一下
OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
可以看到只是传入了ServiceMethod和args参数,于是直接看第三行
第三行
return serviceMethod.callAdapter.adapt(okHttpCall);
这里查看adapt方法会发现CallAdapter<R, T>是个接口,于是我们从第二行创建ServiceMethod时的createCallAdapter()方法来找一下真正调用到的CallAdapter。
private CallAdapter<T, R> createCallAdapter() {
Type returnType = method.getGenericReturnType();
//...省略检查代码
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked 可以看到这里返回了retrofit#callAdapter方法
return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create call adapter for %s", returnType);
}
}
接下来看retrofit#callAdapter方法
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
继续往下看
/**
* Returns the {@link CallAdapter} for {@code returnType} from the available {@linkplain
* #callAdapterFactories() factories} except {@code skipPast}.
*从callAdapterFactories()里拿到可用的CallAdapter
* @throws IllegalArgumentException if no call adapter available for {@code type}.
*/
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
//...省略检查代码
int start = adapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
//...省略代码
}
由于我们之前创建retrofit对象时传入了RxJavaCallAdapterFactory,adapterFactories这个List中有两个元素,第一个为RxJavaCallAdapterFactory,我们传入,另一个为调用Retrofit.Builder.build()时加入的platform.defaultCallAdapterFactory,类型是ExecutorCallAdapterFactory。因此这里会优先返回RxJavaCallAdapter。
来看一下RxJavaCallAdapter的adapt方法
@Override public Object adapt(Call<R> call) {
//添加时默认isAsync = false,scheduler = null
//注意这里默认callFunc为CallExecuteOnSubscribe类型,也就是同步
OnSubscribe<Response<R>> callFunc = isAsync
? new CallEnqueueOnSubscribe<>(call)
: new CallExecuteOnSubscribe<>(call);
OnSubscribe<?> func;
if (isResult) {
func = new ResultOnSubscribe<>(callFunc);
} else if (isBody) {
//这里将OkHttpCall进一步封装
func = new BodyOnSubscribe<>(callFunc);
} else {
func = callFunc;
}
//注意Observable.create(func)中传入的func为OnSubscribe类型
Observable<?> observable = Observable.create(func);
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isSingle) {
return observable.toSingle();
}
if (isCompletable) {
return observable.toCompletable();
}
return observable;
}
自此返回了Observable对象,后面就是RxJava的部分了。
RxJava部分
看Observable#subscribe方法
public final Subscription subscribe(final Observer<? super T> observer) {
if (observer instanceof Subscriber) {
return subscribe((Subscriber<? super T>)observer);
}
if (observer == null) {
throw new NullPointerException("observer is null");
}
//由于这里没有使用Subscriber,故走到这一行
return subscribe(new ObserverSubscriber<T>(observer));
}
继续往下
public final Subscription subscribe(Subscriber<? super T> subscriber) {
return Observable.subscribe(subscriber, this);
}
继续往下
static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
// 省略代码
// new Subscriber so onStart it
subscriber.onStart();
//省略代码
// The code below is exactly the same an unsafeSubscribe but not used because it would
// add a significant depth to already huge call stacks.
try {
// allow the hook to intercept and/or decorate
//重点看这两行
RxJavaHooks.onObservableStart(observable, observable.onSubscribe).call(subscriber);
return RxJavaHooks.onObservableReturn(subscriber);
} catch (Throwable e) {
//省略代码
}
return Subscriptions.unsubscribed();
}
}
关键源码第一行
首先看下这一行
RxJavaHooks.onObservableStart(observable, observable.onSubscribe).call(subscriber);
首先是RxJavaHooks#onObservableStart方法
public static <T> Observable.OnSubscribe<T> onObservableStart(Observable<T> instance, Observable.OnSubscribe<T> onSubscribe) {
Func2<Observable, Observable.OnSubscribe, Observable.OnSubscribe> f = onObservableStart;
if (f != null) {
return f.call(instance, onSubscribe);
}
return onSubscribe;
}
看到这里就不用再往下看了,最后返回的都是onSubscribe,也就是之前的observable.onSubscribe,我们来看看这个onSubscribe是什么
这就需要再回到RxJavaCallAdapter#adapt方法了
//注意Observable.create(func)中传入的func为OnSubscribe类型
Observable<?> observable = Observable.create(func);
在创建observable时我们传入了func变量
进入Observable#create方法
@Deprecated
public static <T> Observable<T> create(OnSubscribe<T> f) {
return new Observable<T>(RxJavaHooks.onCreate(f));
}
//可以看到,onSubscribe就是我们传进来的func
protected Observable(OnSubscribe<T> f) {
this.onSubscribe = f;
}
因此我们回到RxJavaCallAdapter#adapt方法来看下func
//由于isBody = true,我们最终会创建BodyOnSubscribe,传入的callFunc为对OkHttp做的封装
func = new BodyOnSubscribe<>(callFunc);
BodyOnSubscribe(OnSubscribe<Response<T>> upstream) {
//构造函数中,对upstream赋值
this.upstream = upstream;
}
最后,终于可以看下BodyOnSubscribe<T>#call方法了
@Override public void call(Subscriber<? super T> subscriber) {
upstream.call(new BodySubscriber<T>(subscriber));
}
因此我们最后还是走到了CallExecuteOnSubscribe<T>#call方法
@Override public void call(Subscriber<? super Response<T>> subscriber) {
// Since Call is a one-shot type, clone it for each new subscriber.(call是一次性的,每次需要克隆)
Call<T> call = originalCall.clone();
CallArbiter<T> arbiter = new CallArbiter<>(call, subscriber);
subscriber.add(arbiter);
subscriber.setProducer(arbiter);
Response<T> response;
try {
//这里就调用到了OkHttpCall#execute方法,
response = call.execute();
} catch (Throwable t) {
Exceptions.throwIfFatal(t);
arbiter.emitError(t);
return;
}
arbiter.emitResponse(response);
}
最终会调用到OkHttp3的Call.execute(),完成网络请求。
关键源码第二行
return RxJavaHooks.onObservableReturn(subscriber);
当我们继续往下看RxJavaHooks#onObservableReturn方法
public static Subscription onObservableReturn(Subscription subscription) {
Func1<Subscription, Subscription> f = onObservableReturn;
if (f != null) {
//最终是返回f#call
return f.call(subscription);
}
return subscription;
}
由于Func1<T, R>是个接口,我们来看下实际的f是什么。
在RxJavaHooks的init方法中对onObservableReturn初始化。
onObservableReturn = new Func1<Subscription, Subscription>() {
@Override
public Subscription call(Subscription f) {
return RxJavaPlugins.getInstance().getObservableExecutionHook().onSubscribeReturn(f);
}
};
接下来看一下onSubscribeReturn方法
@Deprecated
public <T> Subscription onSubscribeReturn(Subscription subscription) {
// pass through by default
return subscription;
}
可以看到直接返回了传入的Subscription,因此最后返回的是Observable#subscribe方法中创建的new ObserverSubscriber<T>(observer)。
由于篇幅较长,更多关于RxJava线程切换的源码就不再赘述了。
总结
自此,源码解析基本结束。