作为我最爱的一个网络请求库,怎么不来搞搞它呢?
其实Retrofit是OKHTTP的一个封装,它的网络请求还是交给OKHTTP来做的。
我们一般情况下,会这样来做实例化Retrofit:
Retrofit client = new Retrofit.Builder()
.baseUrl("xxxxx")
.addConverterFactory(GsonConverterFactory.create())
.build();
这里使用的是建造者模式,什么是建造者模式呢?将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
具体可以参考:https://www.jianshu.com/p/be290ccea05a
然后我们来看看我们的Retrofit:
首先创建了一个Retrofit.Builder对象,该类是Retrofit的静态内部类:
public static final class Builder {
private final Platform platform;
//网络请求器的工厂,用来产生网络请求其(Call)
private @Nullable okhttp3.Call.Factory callFactory;
//网络请求的url地址
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;
Builder(Platform platform) {
this.platform = platform;
// 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());
}
public Builder() {
//Platform.get()返回一个Platform对象,指定运行平台
this(Platform.get());
}
... ...
}
在方面的代码中,我们是首先会去找到Retrofit运行的平台:
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
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实例了。
然后让converterFactories
添加了一个BuiltInConverters
对象,它是一个内置的转换工厂,它禁止重写它的任何方法,但是这样可以保证当使用converters的正确行为。
Builder对象构建好了后,调用了baseUrl
方法:
public Builder baseUrl(String baseUrl) {
//检查baseUrl不为null
checkNotNull(baseUrl, "baseUrl == null");
//将它转换为一个HttpUrl对象
//在这里会检查baseUrl的正确性
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}
继续:
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
//把URL参数分割成几个路径碎片
List<String> pathSegments = baseUrl.pathSegments();
//检测最后一个碎片以检查URL参数是不是以/结尾
//不是就抛出异常。
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
//给baseUrl赋值
this.baseUrl = baseUrl;
return this;
}
添加完baseUrl后,我们就会添加数据转换工厂:addConverterFactory(GsonConverterFactory.create())
首先我们看一下GsonConverterFactory
的创建:
public static GsonConverterFactory create() {
return create(new Gson());
}
@SuppressWarnings("ConstantConditions") // Guarding public API nullability.
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new GsonConverterFactory(gson);
}
private GsonConverterFactory(Gson gson) {
this.gson = gson;
}
可以看到,它创建了一个Gson对象,将Gson对象封装起来了。
/** Add converter factory for serialization and deserialization of objects. */
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
上面就是给converterFactories添加了一个factory。
接下来,调用build
方法,建造Retrofit对象:
public Retrofit build() {
//必须要有baseUrl
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//网络请求执行器
//如果没有callFactory,默认使用OKHttpClient
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> adapterFactories = new ArrayList<>(this.adapterFactories);
//添加一个默认的网络请求适配工厂
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
//在Builder构造的时候,添加了一个BuildInConverters()
//数据转换工厂集合
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
//创建Retrofit对象
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
接下来,我们来看看Retrofit的构造:
public final class Retrofit {
// 网络请求配置对象(对网络请求接口中方法注解进行解析后得到的对象)
// 作用:存储网络请求相关的配置,如网络请求的方法、
//数据转换器、网络请求适配器、网络请求工厂、基地址等
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
final okhttp3.Call.Factory callFactory;
final HttpUrl baseUrl;
final List<Converter.Factory> converterFactories;
final List<CallAdapter.Factory> adapterFactories;
final @Nullable Executor callbackExecutor;
final boolean validateEagerly;
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
@Nullable Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
//只可以读,不能写
this.converterFactories = unmodifiableList(converterFactories); // Defensive copy at call site.
//只可以读,不能写
this.adapterFactories = unmodifiableList(adapterFactories); // Defensive copy at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
... ...
}
可以看到,Retrofit中的成员变量和Builder中的差不多,在构造Retrofit对象的时候,进行赋值。
当我们构造好了Retrofit后,我们会像这样进行网络请求,以get请求为例:
public interface GetService {
@GET("book/{id}")
Call<String> getRequest(@Path("id") int id);
}
GetService service = client.create(GetService.class);
Call<String> call = service.getRequest(1);
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
}
@Override
public void onFailure(Call<String> call, Throwable t) {
}
});
首先我们调用create
方法得到GetService 对象:
在这是, Retrofit是通过外观模式&代理模式,使用create方法创建网络请求接口实例:
public <T> T create(final Class<T> service) {
//验证service是interface
Utils.validateServiceInterface(service);
if (validateEagerly) {
//判断是否需要提前验证
//默认为false
eagerlyValidateMethods(service);
}
//创建网络请求接口的动态代理对象,即通过动态代理创建网络请求接口实例
//该动态代理主要是为了拿到网络请求接口实例上的所有注解
return (T) Proxy.newProxyInstance(
service.getClassLoader(), //动态生成接口实现类
new Class<?>[] { service }, //动态创建实例
new InvocationHandler() { //代理类的方法的调用会交给它的invoke方法
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)throws Throwable {
//proxy是代理类对象
//method是调用的代理类的哪个方法
//args是方法的餐忽
// 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);
}
});
}
在上面的代码中,我们可以看到的是,主要是调用了Proxy.newProxyInstance
方法,在这里主要使用到了动态代理,什么是动态代理呢?代理类在程序运行时创建的代理方法被称为动态代理,也就是说,在这种情况下,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。
关于动态代理,可以参考:https://juejin.im/post/5ad3e6b36fb9a028ba1fee6a
我们先看看Proxy.newProxyInstance
方法中做了什么:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
//查找或生成指定的代理类
Class<?> cl = getProxyClass0(loader, intfs);
//得到cl的构造器
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
//检查cl的访问权限
if (!Modifier.isPublic(cl.getModifiers())) {
// Android-changed: Removed AccessController.doPrivileged
cons.setAccessible(true);
}
//返回它的实例
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
在这里,通过Proxy工具,为委托类的接口自动生成一个代理对象,后续的方法调用都是这个代理对象进行发起的,最终会执行到InvocationHandler#invoke
方法。
然后我们看看这里InvocationHandler#invoke
方法的实现:
@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);
}
//关注1
//读取网络请求接口里的方法,并根据前面的配置好的属性配置serviceMethod对象
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
//关注2
//根据配置好的serviceMethod对象创建OkHttpCall对象
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//关注点3
//调用OkHttp,并根据oKHttpCall返回Call(不考虑RxJava)
return serviceMethod.callAdapter.adapt(okHttpCall);
}
我们先看关注点1:
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
我们先看看看ServiceMethod是什么:
Adapts an invocation of an interface method into an HTTP call
将接口方法的调用调整为一个HTTP call
也就是哦说,一个serviceMethod对象对应于网络请求接口里的一个方法
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache
= new ConcurrentHashMap<>();
ServiceMethod<?, ?> loadServiceMethod(Method method) {
//在创建ServiceMethod对象前,先看serviceMethodCach有没有缓存之前创建过的网络请求
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
//设置同步锁
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
//创建ServiceMethod实例
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
然后我们看看ServiceMethod的创建:
首先是new ServiceMethod.Builder<>(this, method)
:
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
//获取网络请求接口方法里的注释
this.methodAnnotations = method.getAnnotations();
//获取网络请求接口方法里的参数类型
this.parameterTypes = method.getGenericParameterTypes();
//获取网络请求接口方法里的注释内容
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
然后调用build
方法:
public ServiceMethod build() {
//根据网络请求接口方法的返回值和注解类型,从Retrofit对象中获取对应的网络请求适配器
callAdapter = createCallAdapter();
//获得该网络适配器返回的数据类型
//如Call<String>
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?");
}
//数据转换器
responseConverter = createResponseConverter();
//解析网络请求接口方法中的注解
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;
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);
}
if (relativeUrl == null && !gotUrl) {
throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError("Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError("Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError("Multipart method must contain at least one @Part.");
}
return new ServiceMethod<>(this);
}
我们一个一个的看
先看如何得到的网络请求适配器:
private CallAdapter<T, R> createCallAdapter() {
//得到返回类型
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError("Service methods cannot return void.");
}
//方法的注解
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
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.java
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = adapterFactories.indexOf(skipPast) + 1;
//遍历 CallAdapter.Factory 集合寻找合适的工厂(该工厂集合在第一步构造 Retrofit 对象时进行添加
//在这里是默认的:ExecutorCallAdapterFactory
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
... ...
}
接下来是获取数据转换器:
private Converter<ResponseBody, T> createResponseConverter() {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create converter for %s", responseType);
}
}
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
checkNotNull(type, "type == null");
checkNotNull(annotations, "annotations == null");
int start = converterFactories.indexOf(skipPast) + 1;
//循环遍历,得到数据转换器
//在这里是 GsonResponseBodyConverter
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter<ResponseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
接下来就是解析方法的注解:
private void parseMethodAnnotation(Annotation annotation) {
if (annotation instanceof DELETE) {
parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
} else if (annotation instanceof GET) {
parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
} else if (annotation instanceof HEAD) {
parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
if (!Void.class.equals(responseType)) {
throw methodError("HEAD method must use Void as response type.");
}
} else if (annotation instanceof PATCH) {
parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
} else if (annotation instanceof POST) {
parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
} else if (annotation instanceof PUT) {
parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
} else if (annotation instanceof OPTIONS) {
parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
} else if (annotation instanceof HTTP) {
HTTP http = (HTTP) annotation;
parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
} else if (annotation instanceof retrofit2.http.Headers) {
String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
if (headersToParse.length == 0) {
throw methodError("@Headers annotation is empty.");
}
//添加header
headers = parseHeaders(headersToParse);
} else if (annotation instanceof Multipart) {
if (isFormEncoded) {
throw methodError("Only one encoding annotation is allowed.");
}
isMultipart = true;
} else if (annotation instanceof FormUrlEncoded) {
if (isMultipart) {
throw methodError("Only one encoding annotation is allowed.");
}
isFormEncoded = true;
}
}
在这些步骤做完后,就构建一个ServiceMethod:
ServiceMethod(Builder<R, T> builder) {
this.callFactory = builder.retrofit.callFactory();
this.callAdapter = builder.callAdapter;
this.baseUrl = builder.retrofit.baseUrl();
this.responseConverter = builder.responseConverter;
this.httpMethod = builder.httpMethod;
this.relativeUrl = builder.relativeUrl;
this.headers = builder.headers;
this.contentType = builder.contentType;
this.hasBody = builder.hasBody;
this.isFormEncoded = builder.isFormEncoded;
this.isMultipart = builder.isMultipart;
this.parameterHandlers = builder.parameterHandlers;
}
我们可以总结一下,是如何得到ServiceMethod的:
- 先从
serviceMethodCache
根据method,查询是否存在关于这个method的ServiceMethod - 如果存在,就直接返回
- 如果不存在,就调用
new ServiceMethod.Builder<>(this, method).build();
创建ServiceMethod- 先得到网络适配器callAadpter,如果进行设置,就是默认的,并得到responseType。
- 得到数据转换器responseConverter,一般我们会使用GsonConverterFactory,它会调用
responseBodyConverter
方法,得到Gson的数据转换器:GsonResponseBodyConverter
- 然后遍历循环方法的注解,解析方法的注解,得到
httpMethod
,hasBody
,relativeUrl
,relativeUrlParamNames
,headers
- 接下来遍历循环方法的参数,为每一个方法的参数创建一个ParameterHandler<?>对象并解析每个参数使用的注解类型
- 创建ServiceMethod,返回
- 将返回来的ServiceMethod保存到
serviceMethodCache
接下来,回到invoke方法,我们看关注2:
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
在这里创建了一个OkHttpCall实例,OkHttpCall实现了Call<T>
:
final class OkHttpCall<T> implements Call<T> {
private final ServiceMethod<T, ?> serviceMethod;//包含了所有网络请求参数信息
private final @Nullable Object[] args; //接口参数
private volatile boolean canceled;
@GuardedBy("this")
private @Nullable okhttp3.Call rawCall;
@GuardedBy("this")
private @Nullable Throwable creationFailure; // Either a RuntimeException or IOException.
@GuardedBy("this")
private boolean executed;
OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
... ...
}
创建好了OkHttpCall之后,我们看关注点3:
return serviceMethod.callAdapter.adapt(okHttpCall);
在这里,我们没有设置网络请求适配器,那么就会使用Retrofit默认的:ExecutorCallAdapterFactory
中的一个匿名对象
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;
}
@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;
}
... ....
}
}
这里采用了装饰模式,ExecutorCallbackCall = 装饰者,而里面真正去执行网络请求的还是OkHttpCall
使用装饰模式的原因:希望在OkHttpCall发送请求时做一些额外操作。这里的额外操作是线程转换,即将子线程切换到主线程
在接口的代理实例创建好了后,我们会调用它的方法得到一个Call实例:
Call<String> call = service.getRequest(1);
我们知道,service
对象实例上是动态代理对象Proxy.newProxyInstance()
,并不是真正的网络请求接口创建的对象。
当这个代理对象调用getRequest
方法的时候,会被这个拦截,调用自身的InvocationHandler # invoke()
。
然后就会创建一个Call对象返回。
进行网络请求
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
}
@Override
public void onFailure(Call<String> call, Throwable t) {
}
});
我们知道,在这里call是ExecutorCallAdapterFactory
的实例:
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
//delegate是OkHttpCall的实例
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
//线程切换,主要是通过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.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
我们看看OkHttpCall的enqueue
方法:
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
//创建OkHttp的Request对象,在封装成OkHttp.call
call = rawCall = createRawCall();
} catch (Throwable t) {
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
//发送网络请求
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response<T> response;
try {
//解析返回数据
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
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();
}
}
});
}
我们先看看它是怎么创建okhttp3.Call call:
private okhttp3.Call createRawCall() throws IOException {
Request request = serviceMethod.toRequest(args);
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
@Override public Call newCall(Request request) {
return new RealCall(this, request, false /* for web socket */);
}
我们可以看到,它创建了OkHttp的RealCall对象,然后进行网络请求,之后的操作就交给了OkHttp,
如果请求成功,就会到okhttp3.Callback()
的onResponse
方法,在该方法中,解析response:
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
// Remove the body's source (the only stateful object) so we can pass the response along.
rawResponse = rawResponse.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
if (code < 200 || code >= 300) {
try {
// Buffer the entire body to avoid future I/O.
ResponseBody bufferedBody = Utils.buffer(rawBody);
return Response.error(bufferedBody, rawResponse);
} finally {
rawBody.close();
}
}
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
T body = serviceMethod.toResponse(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
// If the underlying source threw an exception, propagate that rather than indicating it was
// a runtime exception.
catchingBody.throwIfCaught();
throw e;
}
}
可以看到,主要调用了serviceMethod.toResponse(catchingBody)
,进行body解析,在这个方法中,会调用GsonResponseBodyConverter.convert
方法,进行json数据解析。
接下来,会调用callSuccess
方法:
private void callSuccess(Response<T> response) {
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
这个callback是在调用delegate.enqueue
方法时,传入的参数,之后到这个callback的回调中:
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);
}
});
}
});
然后会调用callbackExecutor.execute(Runnable)
方法,callbackExecutor是在Retrofit实例在创建的时候,被初始化的:
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
... ...
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
可以看到,之后的操作就交给了Handler,该Handler是主线程的Handler,因此就实现线程切换。