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)
- Java 面试题
- String、StringBuffer、StringBuilder 的区别?
- Java 中的四种引用
- 接口和抽象类的本质区别
- 集合框架
- 集合概述
- ArrayList 源码分析
- LinkedList 源码分析
- HashMap 源码分析
- LinkedHashMap 源码分析
- Android提供的 LruCache 的分析
- LinkedList 和 ArrayList 的区别
- 多线程
- 实现多线程的几种方式
- 线程的几种状态
- Thread 的 start() 和 run() 的区别
- sleep() 、yield() 和 wait() 的区别 ?
- notify() 和 notifyAll() 的区别?
- 保证线程安全的方式有哪几种?
- Synchronized 关键字
- volatile 和 synchronized 的区别?
- 如何正确的终止一个线程?
- ThreadLocal 原理分析
- 线程池
- 多线程的三个特征
- 五种线程池,四种拒绝策略,三种阻塞队列
- 给定三个线程如何顺序执行完以后在主线程拿到执行结果
- Java 内存模型
- 判定可回收对象算法
- equals 与 == 操作符
- 类加载机制
- 类加载简单例子
- 算法
- 时间、空间复杂度
- 冒泡排序
- 快速排序
- 链表反转
- IO
- 泛型
- Kolin 面试题
- Android 面试题
- Handler 线程间通信
- Message、MessageQueue、Looper、Handler 的对象关系
- Handler 使用
- Handler 源码分析
- HandlerThread
- AsyncTask
- IntentService
- 三方框架
- Rxjava
- rxjava 操作符有哪些
- 如何解决 RxJava 内存泄漏
- Rxjava 线程切换原理
- map和 flatmap 的区别
- Databinding引起的 java方法大于 65535 的问题
- Glide
- Glide 的缓存原理
- Glide 是如何和生命周期绑定的?不同的Context 有什么区别?
- Glide 、Picasso 、的区别,优劣势,如何选择?
- Jetpack
- 源码分析
- EventBus
- EventBus 源码分析
- RxBus 替代 EventBus
- OkHttp
- OkHttp 源码分析
- OkHttp 缓存分析
- RxPermission
- RxPermission 源码分析
- Retrofit
- create
- Retrofit 源码分析
- 优化
- 启动优化
- 布局优化
- 绘制优化
- 内存优化
- 屏幕适配
- 组件
- Activity
- Frgment
- Service
- ContentProvider
- BroadcastReceiver
- 进程间通信
- Binder机制和AIDL
- AILD 中的接口和普通的接口有什么区别
- in、out、inout 的区别
- Binder 为什么只需要拷贝一次
- 在android中,请简述jni的调用过程
- 生命周期
- Activity 生命周期
- Fragment 生命周期
- Service 生命周期
- onSaveInstanceState() 与 onRestoreIntanceState()
- 前沿技术
- 组件化
- 模块化
- 插件化
- 热更新
- UI - View
- Android 动画
- 事件分发机制
- WebView
- 系统相关
- 谈谈对 Context 的理解
- Android 版本
- App应用启动流程
- App 的打包
- App 的加固
- App 的安装
- Activity 启动流程
- ClassLoader
- Lru 算法加载 Bitmap 三级缓存原理
- Parcelable 和 Serializable 的区别
- Activity的启动流程
- 相关概念
- 网络相关
- Http
- Https
- Http 和 Https 的区别
- 为什么要进行三次握手和四次挥手?
- OkHttp使用Https访问服务器时信任所有证书
- 设计模式
- 单例模式
- 构建者模式
- 工厂模式
- 外观模式
- 代理模式