前提
友情提醒
1.这篇文章主要讲retrofit如何request 和 response 2.不会详细到每个api 3.文章会以一个flow 来讲解
上图

retrofit初始化配置
private Retrofit createRetrofit(OkHttpClient client, String url) {
return new Retrofit.Builder()
.baseUrl(url)
.client(client)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
这里我们只说一下主要的东西,大家都知道retrofit的adapter 我们根据我们api请求的不同设置不同的adapter来让retrofit执行不同的操作,当我们在设置他的CallAdapter时,点进源码可以看到,retrofit把这个CallAdapter存入了一个集合中
final List
然后通过build把这个集合回传给了retrofit的这个全局边变量List<CallAdapter.Factory> adapterFactories保存着这些CallAdapter,仔细看的同学会发现,retrofit会默认给你添加一个CallAdapter
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
以上就说到这里,知道有个CallAdapterFactory集合存在Retrofit的全局变量中。
配置Api
public interface Api {
@Multipart
@POST("upload")
Observable postVoice(@Part("deviceNo") RequestBody deviceNo,
@Part("duration") RequestBody duration,
@Part("title") RequestBody title,
@Part MultipartBody.Part file);
@GET("selfList")
Call getVoiceList(@Query("deviceNo")String deviceNo);
}
Request
当我们要发起请求的时候,我们是不是这样做,拿到之前配置好的Retrofit然后调用他的Create方法然后把相应的api传入. Retroift.create(Api.class)这样的操作
现在我们进入源码查看这个retrofit最亮点的地方(create(api.class)),通过反射实例化接口,然后拦截接口中的方法,来做api的请求。返回给这个method。
先把源码晾上然后讲解
public T create(final Class service) {
·······省略的代码·······
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 {
·······省略的代码·······
ServiceMethod
上面的代码已经是把无关紧要的代码剔除了,我们只看重要的代码
-
我们可以看到create这个方法通过代理反射实例化我们传进来的api接口
-
然后通过
ServiceMethod和OkHttpCall来拿到这个方法的相关参数,来invoke这个方法 -
最后通过
serviceMethod.callAdapter.adapt(okHttpCall)把请求到的值返回回去
其实在最后一步大家应该明白了,请求是来自于ServiceMethod的callAdapter参数,然后通过adapt来进行okhttp请求。
下面我会讲解这个calladapter 如何而来。
ServiceMethod如何发起请求
这是一个流程哈,我们这时候进入代码core部分,他的ServiceMethod时通过retrofit的loadServiceMethod拿到的实例化对象。我们进入这个方法可以看到其实这是一个全局的ServiceMethod的cacheMap
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
但是不论他做不做缓存肯定有new 的地方,然后才能加入缓存中吧。从上图代码中我们可以看到这个new 的地方。
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
这下清楚了ServiceMethod哪里来的了吧,通过new ServiceMethod.Builder<>(this, method).build()这句话来的。看源码不都这样吗!一步一步的进入源码然后理解他的每一层 意思和目的。to be continue
上ServiceMethod.Builder的源码,我们只看重要的代码,其他的忽略
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
public ServiceMethod build() {
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
·······省略的代码·······
}
小伙子们,是不是看到了我们一直最关心的calladapter了,在build的时候通过createCallAdapter来初始化了这个值。进入方法看个究竟
private CallAdapter
看到了吧,小伙伴这个calladapter 来自于retrofit里面的方法,我们在loadServiceMethod的时候还记得这句代码吗?new ServiceMethod.Builder<>(this, method).build()我们把retrofit传了进来,然后这里通过retrofit的callAdapter来获取ServiceMethod的adapter。下面是retrofit的源码获取c
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
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;
}
}
·······省略的代码·······
}
我感觉只要不眼瞎都能看到这个serviceMethod的calladapter 是来自于我们retrofit之前进行初始化配置时候的RxJavaCallAdapterFactory.create() 其实我们可以在之前的图中看到这个flow,.addCallAdapterFactory(RxJavaCallAdapterFactory.create())最终指向的是ServiceMethod的CallAdapter。
进入RxJavaCallAdapterFactory的源码吧。其实这里的代码并不多,只不过有些杂乱。下面我会把不需要的代码过滤
public final class RxJavaCallAdapterFactory extends CallAdapter.Factory {
/**
* Returns an instance which creates synchronous observables that do not operate on any scheduler
* by default.
*/
public static RxJavaCallAdapterFactory create() {
return new RxJavaCallAdapterFactory(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 RxJavaCallAdapterFactory createAsync() {
return new RxJavaCallAdapterFactory(null, true);
}
/**
* Returns an instance which creates synchronous observables that
* {@linkplain Observable#subscribeOn(Scheduler) subscribe on} {@code scheduler} by default.
*/
@SuppressWarnings("ConstantConditions") // Guarding public API nullability.
public static RxJavaCallAdapterFactory createWithScheduler(Scheduler scheduler) {
if (scheduler == null) throw new NullPointerException("scheduler == null");
return new RxJavaCallAdapterFactory(scheduler, false);
}
private final @Nullable Scheduler scheduler;
private final boolean isAsync;
private RxJavaCallAdapterFactory(@Nullable Scheduler scheduler, boolean isAsync) {
this.scheduler = scheduler;
this.isAsync = isAsync;
}
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
·······省略的代码·······
if (isCompletable) {
return new RxJavaCallAdapter(Void.class, scheduler, isAsync, false, true, false, true);
}
·······省略的代码·······
return new RxJavaCallAdapter(responseType, scheduler, isAsync, isResult, isBody, isSingle,
false);
}
}
可以看到这个RxJavaCallAdapterFactory继承了CallAdapter.Factory,实现了他的get方法,在get方法中我们就可以拿到这个CallAdapter,然后进行我们的adapt方法请求。 从上面的代码可以看到真正实现CallAdapter的是 RxJavaCallAdapter 我们继续看看这个RxJavaCallAdapter到底干了什么!!!同样我会过滤不需要的代码
final class RxJavaCallAdapter implements CallAdapter
好了,这下清晰了许多
这个RxJavaCallAdapter实现了CallAdapter的adapt请求。然后在adapt中需要传入参数就是Call 然而我们可以回到图中看到,OkHttpCall正好是Call的实现类。这里就是上图中的右边部分。
可以在这个方法中看到了,同步异步请求对应的不一样的然后调用不同的CallEnqueueOnSubscribe,CallExecuteOnSubscribe进行request
进入CallEnqueueOnSubscribe源码看看
final class CallEnqueueOnSubscribe implements OnSubscribe
看到了吧这里终于发起请求了可以看到,执行了OkHttpCall.enqueue请求,同时通过arbiter.emitResponse(response);把参数回调了回来。
这就是retrofit的请求flow。
思路整理
-
配置retrofit(addCallAdapterFactory)
-
创建ApiService
-
通过retrofit的create实例化ApiService接口
-
创建ServiceMethod
-
通过retrofit的AdapterFactories拿到ServiceMethod的CallAdapter
-
创建OkHttpCall请求工具类
-
通过ServiceMethod的CallAdapter的adapt进行请求并把第六步写好的call当参数传给adapt。
-
把ServiceMethod请求回来的参数返回给对应的ApiService里面的方法
-
请求完成










