ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
Retrofit 源码分析 [TOC] 开发中现在应该都是使用 Retrofit 进行网络请求了,其实本质上 Retrofit 是一个对 OkHttp 进行进一步封装的框架,也就是使用 Retrofit 进行网络请求,本质上还是使用的 OkHttp 进行网络,只不过 Retrofit 的封装让我们在使用 OkHttp 的时候更加方便了。 下面就来分析下 Retrofit 的源码 ## 请求流程 下面通过豆瓣 API 进行简单的请求: 定义接口:MovieService ```java public interface MovieService { /** * 请求top250接口 * @param start * @param count * @return */ @GET("top250") Call<MovieEntity> getTopMovie(@Query("start") int start, @Query("count") int count); } ``` 这里使用的 MovieEntity 代码就不贴了,可以根据接口返回数据自己生成。 然后在 Activity 中创建 Retrofit 对象: ```java //进行网络请求 private void getMovie() throws IOException { String baseUrl = "https://douban.uieee.com/v2/movie/"; Retrofit retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); MovieService movieService = retrofit.create(MovieService.class); Call<MovieEntity> call = movieService.getTopMovie(0, 10); call.enqueue(new Callback<MovieEntity>() { @Override public void onResponse(Call<MovieEntity> call, final Response<MovieEntity> response) { runOnUiThread(new Runnable() { @Override public void run() { Log.d("response: ", response.body().toString()); retrofitShow.setText(response.body().getTitle() + response.body().getCount()); } }); } @Override public void onFailure(Call<MovieEntity> call, final Throwable t) { runOnUiThread(new Runnable() { @Override public void run() { Log.d("failure : ", t.getMessage()); } }); } }); } ``` 这里首先通过 Retrofit 的内部类 Builder 创建出一个 Retrofit 对象。 ### 创建 Retrofit 来看下 Retrofit 的一些属性: ```java public final class Retrofit { // 根据接口中的方法名,存储方法对应的 Service 对象。这里的方法指的就是 MovieService 中定义的 // getTopMovie方法,ServiceMethod 就是 getTopMovie 接口方法对应的解析信息 private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>(); // 网络请求器的工厂,用来生成网络请求器,默认使用的OkHttp final okhttp3.Call.Factory callFactory; // 请求的url地址等信息,包括scheme、username、password、host、port、path、query、fragment等信息 final HttpUrl baseUrl; // 数据转换器的工厂的集合,存储数据转换器工厂,来生成数据转换器 final List<Converter.Factory> converterFactories; // 网络请求适配器工厂的集合,存放请求适配器工厂,来声场请求适配器 final List<CallAdapter.Factory> adapterFactories; // 回调方法执行器,在 Android 上默认是封装了 handler 的 MainThreadExecutor, // 默认作用是:切换线程(子线程 -> 主线程) final @Nullable Executor callbackExecutor; // 是否提前创建 ServiceMethod 缓存的开关,如果为true,则在调retrofit.create(MovieService.class); // 的时候就会生成 ServiceMethod 并添加到缓存里面,如果为false,则在movieService.getTopMovie(0, 10); 的时候才会生成 ServiceMethod 并添加到缓存里面。 final boolean validateEagerly; } ``` Retrofit 主要就上面的这些属性,他们是由 Retrofit 的内部类 Builder 来生成的,在调用 Builder 的 build() 方法的时候,会创建 Retrofit 对象。 首先使用 new Retrofit.Builder() 创建一个 Builder 对象,来看下 Builder 类: ```java public static final class Builder { // 当前的平台 private final Platform platform; private @Nullable okhttp3.Call.Factory callFactory; private HttpUrl baseUrl; private final List<Converter.Factory> converterFactories = new ArrayList<>(); private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>(); private @Nullable Executor callbackExecutor; private boolean validateEagerly; // 上面的一些属性和 Retrofit 中一致,用来给 Retrofit 赋值用 Builder(Platform platform) { this.platform = platform; //首先添加内置转换器工厂。这可以防止被覆盖,而且确保使用使用所有类型的转换器时的正确行为 converterFactories.add(new BuiltInConverters()); } public Builder() { this(Platform.get()); } Builder(Retrofit retrofit) { platform = Platform.get(); callFactory = retrofit.callFactory; baseUrl = retrofit.baseUrl; converterFactories.addAll(retrofit.converterFactories); adapterFactories.addAll(retrofit.adapterFactories); // Remove the default, platform-aware call adapter added by build(). adapterFactories.remove(adapterFactories.size() - 1); callbackExecutor = retrofit.callbackExecutor; validateEagerly = retrofit.validateEagerly; } } ``` 在生成 Builder 对象的时候,会调用无参的构造方法,然后获取当前平台,然后再调用有参的构造方法。 看下 Platform.get(): ```java class Platform { // 类加载的时候就创建好了 Platform private static final Platform PLATFORM = findPlatform(); // 获取平台信息 static Platform get() { return PLATFORM; } // 通过反射获取当前平台,我们是 Android ,所以返回 Android 平台 private static Platform findPlatform() { try { Class.forName("android.os.Build"); if (Build.VERSION.SDK_INT != 0) { return new Android(); } } catch (ClassNotFoundException ignored) { } try { Class.forName("java.util.Optional"); return new Java8(); } catch (ClassNotFoundException ignored) { } return new Platform(); } } ``` 在这里返回的是 Android 平台: ```java static class Android extends Platform { // 获取 Android 平台默认的callback 回调处理器,这里返回的是MainThreadExecutor // MainThreadExecutor 是 Android 的一个静态内部类,里面初始化了 主线程的 Handler // 也就是最后收到服务器响应以后切换到主线程处理消息。 @Override public Executor defaultCallbackExecutor() { return new MainThreadExecutor(); } // 获取默认的请求适配器工厂,这里使用的 ExecutorCallAdapterFactory。用于在执行异步请求时候在 // ExecutorCallAdapterFactory 中生成的Executor 中执行。 // Retrofit 提供了四中请求适配器,分别为:ExecutorCallAdapterFactory/(Rxjava1/2)/Guava/java8 // 提供的请求适配器:https://github.com/square/retrofit/wiki/Call-Adapters @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) { if (callbackExecutor == null) throw new AssertionError(); return new ExecutorCallAdapterFactory(callbackExecutor); } static class MainThreadExecutor implements Executor { private final Handler handler = new Handler(Looper.getMainLooper()); @Override public void execute(Runnable r) { handler.post(r); } } } ``` 然后调用了有参的构造方法完成了Builder 对象的创建并添加了内置的转换器工厂。 上面是创建 Builder 对象的过程,在获取完对象并且设置完参数以后,最后调用的 .build() 方法: ```java public Retrofit build() { // 这里指定了,我们不能设置为 null 的 baseUrl if (baseUrl == null) { throw new IllegalStateException("Base URL required."); } // 这里设置了网络请求工厂,如果没有设置,就使用OkHttpClient作为网络请求工厂 okhttp3.Call.Factory callFactory = this.callFactory; if (callFactory == null) { callFactory = new OkHttpClient(); } // 设置回调方法执行器,如果没有指定,就使用上面Android 平台指定的执行器(也就是回调到主线程) Executor callbackExecutor = this.callbackExecutor; if (callbackExecutor == null) { callbackExecutor = platform.defaultCallbackExecutor(); } // 获取自定义设置的请求适配器工厂集合(这里是通过 addCallAdapterFactory 添加的),添加到 adapterFactories ,然后再把上面 platform // 设置的平台默认网络请求适配器工厂也加入 adapterFactories List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories); adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor)); // 获取自定义设置的数据转换器工厂集合(这里是通过addConverterFactory 添加的), // 添加到 converterFactories,注意此时在创建 Builder 的时候已经把内置的转换器工厂添加了进去 List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories); // 调用Retrofit 的构造方法创建 Retrofit。需要注意的是 validateEagerly 默认是false的, // 也就是不提前缓存ServiceMethod。 return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories, callbackExecutor, validateEagerly); } ``` 上面完成了 Retrofit 的创建过程,然后再来看创建接口代理对象的过程: ### 创建接口代理对象 接口代理对象的创建是使用下面代码创建的: ```java MovieService movieService = retrofit.create(MovieService.class); ``` 这里是通过创建好的 Retrofit的 create 方法,传入 MoviceService 接口创建的: ```java public <T> T create(final Class<T> service) { // 接口有效性校验 Utils.validateServiceInterface(service); // 这个就是前面说的控制是否会提前获取ServiceMethod 并且缓存的判断,默认是 false的 // 如果设置为 true,则执行 eagerlyValidateMethods if (validateEagerly) { //提前创建好 MovieService 接口中的所有方法对应的 ServiceMethod 信息 eagerlyValidateMethods(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 { // 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); } }); } // 提前创建好 MovieService 接口中的所有方法对应的 ServiceMethod 信息 private void eagerlyValidateMethods(Class<?> service) { Platform platform = Platform.get(); // 反射拿到接口中的所有方法 for (Method method : service.getDeclaredMethods()) { // isDefaultMethod 返回的一直是false ,也就是会执行 loadServiceMethod if (!platform.isDefaultMethod(method)) { // 循环创建 loadServiceMethod(method); } } } ``` 这里会调用 loadServiceMethod(method) : #### loadServiceMethod 方法生成并缓存 ServiceMethod ```java // 获取 MovieService 接口中某个方法对应的 ServiceMethod 信息 ServiceMethod<?, ?> loadServiceMethod(Method method) { // 从 缓存 serviceMethodCache 中取方法对应的 ServiceMethod 。 ServiceMethod<?, ?> result = serviceMethodCache.get(method); // 如果取到 ServiceMethod ,直接返回,继续下一个 if (result != null) return result; // 这里没取到,加上同步锁, synchronized (serviceMethodCache) { // 继续获取一次,没取到就去创建一个新的 ServiceMethod,并且添加到缓存 serviceMethodCache中 result = serviceMethodCache.get(method); if (result == null) { // 传入当前的 Retrofit对象和接口中的方法信息, // 使用 ServiceMethod 内部的Builder 类创建 ServiceMethod。 result = new ServiceMethod.Builder<>(this, method).build(); serviceMethodCache.put(method, result); } } // 返回 ServiceMethod return result; } //ServiceMethod 内部类 Builder 的构造方法 Builder(Retrofit retrofit, Method method) { this.retrofit = retrofit;//设置 Retrofit 对象 this.method = method;//设置方法 // 反射拿到方法上所有的注解信息 this.methodAnnotations = method.getAnnotations(); // 反射拿到参数类型信息 this.parameterTypes = method.getGenericParameterTypes(); // 反射拿到参数注解信息 this.parameterAnnotationsArray = method.getParameterAnnotations(); } // 然后调用 build() 构建 ServiceMethod 对象 // 构建 ServiceMethod public ServiceMethod build() { // 调用 createCallAdapter() 生成网络请求适配器 callAdapter = createCallAdapter(); // 拿到返回值类型 responseType = callAdapter.responseType(); if (responseType == Response.class || responseType == okhttp3.Response.class) { throw methodError("'" + Utils.getRawType(responseType).getName() + "' is not a valid response body type. Did you mean ResponseBody?"); } // createResponseConverter() 拿到数据转换器 responseConverter = createResponseConverter(); // 解析方法中的所有注解,主要处理请求类型、Headers、Multipart、FormUrlEncoded等注解类型 for (Annotation annotation : methodAnnotations) { parseMethodAnnotation(annotation); } // 请求类型不能为空 if (httpMethod == null) { throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.)."); } if (!hasBody) { if (isMultipart) { throw methodError( "Multipart can only be specified on HTTP methods with request body (e.g., @POST)."); } if (isFormEncoded) { throw methodError("FormUrlEncoded can only be specified on HTTP methods with " + "request body (e.g., @POST)."); } } // 拿到接口方法里面的参数长度 int parameterCount = parameterAnnotationsArray.length; // 为方法中的每个参数创建一个ParameterHandler<?>对象并解析每个参数使用的注解类型 // 该对象的创建过程就是对方法参数中注解进行解析 // 这里的注解包括:Body、PartMap、Part、FieldMap、Field、Header、QueryMap、Query、Path、Url 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); } ... // 根据当前 Builder 中的信息,创建 ServiceMethod 对象。 return new ServiceMethod<>(this); } ``` 上面调用的 ServiceMethod 的构造方法创建一个 ServiceMethod 对象,来看下 ServiceMethod 的构造方法: ```java ServiceMethod(Builder<R, T> builder) { // 网络请求工厂 this.callFactory = builder.retrofit.callFactory(); // 请求适配器 this.callAdapter = builder.callAdapter; // 请求的baseUrl this.baseUrl = builder.retrofit.baseUrl(); // 数据转换器 this.responseConverter = builder.responseConverter; // http 请求类型 this.httpMethod = builder.httpMethod; // 相对地址,和 baseUrl一起构成完整请求地,格式为 baseUrl+relativeUrl this.relativeUrl = builder.relativeUrl; // 请求的请求头信息 this.headers = builder.headers; // 请求类型 this.contentType = builder.contentType; // 是否有 body this.hasBody = builder.hasBody; // form表单类型 this.isFormEncoded = builder.isFormEncoded; // 是否是上传文件 this.isMultipart = builder.isMultipart; // 参数处理器 this.parameterHandlers = builder.parameterHandlers; } ``` 可以看到只是给 ServiceMethod 中的属性赋值。其实这些属性基本上是 ServiceMethod 的全部属性了。 通过上面的eagerlyValidateMethods() 方法调用,也顺便了解了 loadServiceMethod 方法,大概已经了解了 ServiceMethod 的生成过程了,接着看 create 方法: ```java public <T> T create(final Class<T> service) { Utils.validateServiceInterface(service); if (validateEagerly) { eagerlyValidateMethods(service); } // 上面都分析过了,这里直接通过动态代理的方式返回了一个 T 的代理对象,这个T就是传递过来的泛型, // 这个例子中也就是 MovieService。 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 { // 如果传递进来的是 Object类型,那么按照常规执行,事实上正常使用不会传递 Object if (method.getDeclaringClass() == Object.class) { return method.invoke(this, args); } // 这个 isDefaultMethod 是一直返回的 false 的,所以这里也不会执行 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 ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method); ``` 这里通过 loadServiceMethod 生成 ServiceMethod 对象,loadServiceMethod 前面已经分析过了,不再赘述,继续往下看第二行: #### 三行重要代码之 - 第二行 ```java OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args); ``` 这里只是使用第一行生成的 ServiceMethod 对象和方法参数创建一个 OkHttpCall 对象。(这里的参数是在接口代理对象调用具体方法的时候,传递过来的,这里只是返回,并没有实际调用到,只有等到 `movieService.getTopMovie(0, 10);` 这行代码的时候才会调用到). 来看下 OkHttpCall 是啥? ```java // OkHttpCall 继承于 Call ,这个Call 是 final class OkHttpCall<T> implements Call<T> { // 含有所有网络请求参数信息的对象 private final ServiceMethod<T, ?> serviceMethod; // 实际调用接口中方法的参数数组 private final @Nullable Object[] args; // 是否被 取消,用 volatile 保证线程可见性 private volatile boolean canceled; // 实际进行网络请求的 rawCall @GuardedBy("this") private @Nullable okhttp3.Call rawCall; @GuardedBy("this") private @Nullable Throwable creationFailure; // Either a RuntimeException or IOException. @GuardedBy("this") private boolean executed; // 赋值 serviceMethod 和 参数数组,并创建 OkHttpCall 对象。 OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) { this.serviceMethod = serviceMethod; this.args = args; } } ``` 其实这个 OkHttpCall 就是实际用来调用 OkHttp 完成网络请求的类。 #### 三行重要代码之 - 第三行 ```java return serviceMethod.callAdapter.adapt(okHttpCall); ``` 这里首先通过 serviceMethod 对象拿到设置的请求适配器,比如我们可能 会设置的 `RxJava2CallAdapterFactory`。如果没设置,就是返回平台默认的请求适配器,然后调用adapt 方法并传入上面构建好的 okHttpClient 对象。 看下 adapt () 方法 : ```java public interface CallAdapter<R, T> { Type responseType(); T adapt(Call<R> call); /** * Creates {@link CallAdapter} instances based on the return type of {@linkplain * Retrofit#create(Class) the service interface} methods. */ abstract class Factory { 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); } } } ``` 这里是个抽象类,看下默认请求适配器的具体的实现类 `ExecutorCallAdapterFactory` ```java final class ExecutorCallAdapterFactory extends CallAdapter.Factory { final Executor callbackExecutor; ExecutorCallAdapterFactory(Executor callbackExecutor) { this.callbackExecutor = callbackExecutor; } @Override public 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; } // 最终会调用到这里,使用 ExecutorCallbackCall 把传递进来的 // OKHttpCall 包装了起来,最终还是通过 OKHttpCall 请求的 @Override public Call<Object> adapt(Call<Object> call) { return new ExecutorCallbackCall<>(callbackExecutor, call); } }; } static final class ExecutorCallbackCall<T> implements Call<T> { final Executor callbackExecutor; final Call<T> delegate; ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) { this.callbackExecutor = callbackExecutor; this.delegate = delegate; } @Override public void enqueue(final Callback<T> callback) { checkNotNull(callback, "callback == null"); delegate.enqueue(new Callback<T>() { @Override public void onResponse(Call<T> call, final Response<T> response) { callbackExecutor.execute(new Runnable() { @Override public void run() { if (delegate.isCanceled()) { // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation. callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled")); } else { callback.onResponse(ExecutorCallbackCall.this, response); } } }); } @Override public void onFailure(Call<T> call, final Throwable t) { callbackExecutor.execute(new Runnable() { @Override public void run() { callback.onFailure(ExecutorCallbackCall.this, t); } }); } }); } @Override public boolean isExecuted() { return delegate.isExecuted(); } @Override public Response<T> execute() throws IOException { return delegate.execute(); } @Override public void cancel() { delegate.cancel(); } @Override public boolean isCanceled() { return delegate.isCanceled(); } @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone. @Override public Call<T> clone() { return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone()); } @Override public Request request() { return delegate.request(); } } } ``` 然后可以看到,在默认的请求适配器中,adapt 方法把传递进去的 okHttpCall 对象包装了起来,然后返回了。 到这里,create 创建 接口代理对象已经完成了。继续看下一行代码: ### 执行代理对象获得请求对象 ``` Call<MovieEntity> call = movieService.getTopMovie(0, 10); ``` 经过上面的 create 方法得到的 movieService在这里调用了 getTopMovie 方法,这里的 movieSerice是实际上的 MovieService 的代理对象,执行 getTopMovie 的时候,会被动态代理对象 Proxy.newPxoxyInstance 拦截调用 InvocationHandler 的 invoke 方法,invoke 方法有三个参数, ```java public Object invoke(Object proxy, Method method, Object[] args) ``` proxy就是刚才得到的movieSerice,method 就是 getTopMovie ,args 就是 getTopMovie 方法中的 0和10。 接下来就是通过反射获取到 getTopMovie 的注解信息,生成 ServiceMethod ,然后构建 OkHttpCall 对象,再然后调用 adapt 方法返回一个 Call 对象,这里对应的就是 Retrofit 对 OkHttp 中 Call 对象的包装类 OkHttpCall。 ### 执行具体的请求 这里有两种方式,分别是同步请求 execute 和 异步请求 enqueue 。 #### 异步请求 这里以异步请求为例: ```java call.enqueue(new Callback<MovieEntity>() { @Override public void onResponse(Call<MovieEntity> call, final Response<MovieEntity> response) { runOnUiThread(new Runnable() { @Override public void run() { Log.d("response: ", response.body().toString()); retrofitShow.setText(response.body().getTitle() + response.body().getCount()); } }); } @Override public void onFailure(Call<MovieEntity> call, final Throwable t) { runOnUiThread(new Runnable() { @Override public void run() { Log.d("failure : ", t.getMessage()); } }); } }); ``` 调用了call 的 enqueue 方法,也就是 OkHttpCall 的包装类: ExecutorCallbackCall 的 enqueue 方法: ```java @Override public void enqueue(final Callback<T> callback) { checkNotNull(callback, "callback == null"); // 调用内部的 okHttpCall 进行一步请求 delegate.enqueue(new Callback<T>() { @Override public void onResponse(Call<T> call, final Response<T> response) { // 这个地方是 http 请求返回了,然后调用callbackExecutor来把结果切换到主线程中回调 ,这里的我们在构建 Retrofit 对象的时候,选择Android 的时候已经构建好了,使用的是主线程的 Looper。所以可以通过 handler 发送到主线程中去执行。 callbackExecutor.execute(new Runnable() { @Override public void run() { if (delegate.isCanceled()) { // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation. callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled")); } else { callback.onResponse(ExecutorCallbackCall.this, response); } } }); } @Override public void onFailure(Call<T> call, final Throwable t) { // 这个地方是请求错误,同样调用 callbackExecutor来把结果切换到主线程中回调 ,原理同上 callbackExecutor.execute(new Runnable() { @Override public void run() { callback.onFailure(ExecutorCallbackCall.this, t); } }); } }); } ``` 这里的 delegate.enqueue 其实调用的 OkHttpCall 内部的 enqueue 方法: ```java @Override public void enqueue(final Callback<T> callback) { checkNotNull(callback, "callback == null"); // 实际请求的 Call okhttp3.Call call; Throwable failure; synchronized (this) { if (executed) throw new IllegalStateException("Already executed."); executed = true; // 这里给实际请求的 Call 赋值,如果为空,那么调用 createRawCall 生成一个 Call 对象 // createRawCall 实现看下面 call = rawCall; failure = creationFailure; if (call == null && failure == null) { try { call = rawCall = createRawCall(); } catch (Throwable t) { failure = creationFailure = t; } } } if (failure != null) { callback.onFailure(this, failure); return; } if (canceled) { call.cancel(); } // 调用OkHttp 的 异步请求方法 call.enqueue(new okhttp3.Callback() { @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) throws IOException { Response<T> response; try { // 请求成功。使用 parseResponse 生成最终的 Response,在这个 parseResponse中 // 会调用 serviceMethod.toResponse(catchingBody);去调用数据转换适配器的 convert // 方法转换成我们定义的类型,比如Gosn 数据转换器等 response = parseResponse(rawResponse); } catch (Throwable e) { callFailure(e); return; } // 返回最终转换后的 response callSuccess(response); } @Override public void onFailure(okhttp3.Call call, IOException e) { try { callback.onFailure(OkHttpCall.this, e); } catch (Throwable t) { t.printStackTrace(); } } // 回调失败信息 private void callFailure(Throwable e) { try { callback.onFailure(OkHttpCall.this, e); } catch (Throwable t) { t.printStackTrace(); } } // 回调成功信息 private void callSuccess(Response<T> response) { try { callback.onResponse(OkHttpCall.this, response); } catch (Throwable t) { t.printStackTrace(); } } }); } private okhttp3.Call createRawCall() throws IOException { // 调用 serviceMethod.toRequest 创建最后请求的 Request 对象,这个是Okhttp 中的 Request 对象 Request request = serviceMethod.toRequest(args); // 通过 serviceMethod 中的请求工厂创建实际请求的 Call(这个Call 是 OKHttp最终完成请求的Call) // 也就是下面的 newCall 方法 okhttp3.Call call = serviceMethod.callFactory.newCall(request); if (call == null) { throw new NullPointerException("Call.Factory returned null."); } return call; } // 这里是 OkHttp 的代码,创建实际请求的Call @Override public Call newCall(Request request) { return new RealCall(this, request, false /* for web socket */); } ``` 通过在 OkHttpCall 中请求完毕以后,然后再回调到 OkHttpCall 的包装类 ExecutorCallbackCall 的enqueue 方法中,切换线程,然后完成最终请求。 #### 同步请求 同步请求是调用 ```java Response<MovieEntity> response= call.execute(); ``` 同上,这个 call 实际上是 OkHttpCall 的包装类 ExecutorCallbackCall,调用ExecutorCallbackCall 里面的 execute: ```java @Override public Response<T> execute() throws IOException { return delegate.execute(); } ``` 这里比异步请求简单了很多,直接调用内部代理的 OkHttpCall 对象完成请求。也不会涉及到线程的切换,需要注意的是,同步请求在哪个线程调用,就在哪个线程执行,所以不要在主线程中执行同步请求,会报错的。 来看下 OkHttpCall 的同步请求: ```java @Override public Response<T> execute() throws IOException { // 实际请求的OkHttp 的 Call 对象 okhttp3.Call call; synchronized (this) { if (executed) throw new IllegalStateException("Already executed."); executed = true; if (creationFailure != null) { if (creationFailure instanceof IOException) { throw (IOException) creationFailure; } else { throw (RuntimeException) creationFailure; } } // 这里给实际请求的 Call 赋值,如果为空,那么调用 createRawCall 生成一个 Call 对象 // createRawCall 实现看下面 call = rawCall; if (call == null) { try { call = rawCall = createRawCall(); } catch (IOException | RuntimeException e) { creationFailure = e; throw e; } } } if (canceled) { call.cancel(); } // 调用Okhttp 中的 call 的同步方法完成请求。 // 请求成功以后。使用 parseResponse 生成最终的 Response,在这个 parseResponse中 // 会调用 serviceMethod.toResponse(catchingBody);去调用数据转换适配器的 convert // 方法转换成我们定义的类型,比如Gosn 数据转换器等 return parseResponse(call.execute()); } ``` 到这里一个简易的 Retrofit 流程已经分析完了,其中里面的数据适配器和数据转换器没有细讲,文中的代码都是使用的默认的数据适配器和默认的数据转换器讲的。 后面有时间可以分析下 RxjavaCallAdapterFactory 数据适配器工厂是怎么实现的。 ## 总结 通过上面的分析我们可以看到 Retrofit 是在内部通过大量的设计模式对 OkHttp 库的又一层封装,让我们使用者更加方便的进行网络请求。 其内部的核心就是通过动态代理,将定义的网络请求接口生成对应的代理对象,然后在执行代理对象方法调用的时候,会通过反射把调用的方法信息封装在 ServiceMethod 中,拿到 OkHttpCall 的包装类,最后通过包装类里面调用 OkhttpCall 调用 OkHttp 的方式完成网络请求。 参考文章: [Android:手把手带你 深入读懂 Retrofit 2.0 源码](https://www.jianshu.com/p/0c055ad46b6c) [Android主流三方库源码分析(二、深入理解Retrofit源码)](https://jsonchao.github.io/2018/12/09/Android%E4%B8%BB%E6%B5%81%E4%B8%89%E6%96%B9%E5%BA%93%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%EF%BC%88%E4%BA%8C%E3%80%81%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Retrofit%E6%BA%90%E7%A0%81%EF%BC%89/) [Retrofit分析-漂亮的解耦套路](https://www.jianshu.com/p/45cb536be2f4)