前提
友情提醒
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里面的方法
-
请求完成