文章目录
概述
Retrofit适用于Android和Java的类型安全的HTTP客户端。一个RESTful的基于OKHttp的Http网络框架。简单网络请求,提高开发效率。
使用如下
- 定义
Java接口
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
- 构建
Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
- 生成
Java接口对象
GitHubService service = retrofit.create(GitHubService.class);
- 调用对象的方法获取对应的
Call
Call<List<Repo>> repos = service.listRepos("octocat");
- 也就是调用
Call的execute方法进行同步网络请求,或者调用enqueue进行异步的网路请求。
接下来我们会根据一一分析这5个步骤。基于Retrofit2.4.0分析。
Java接口定义
由于Retrofit使用的动态代理进行生成接口对象的,我们的网络请求的接口必须是Java接口。
Retrofit定义了许多的注解。定义网络请求的接口就是通过这些注解来完成的。
注解会保留到运行时,因为Retrofit需要根据这些注解去解析运行时的参数。
比如GET注解
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface GET {
String value() default "";
}
GET方法上的注解,注解保留到运行时。
构建Retrofit对象
使用了Builder模式来创建Retrofit对象。Retrofit.Builder拥有很多创建Retrofit的配置项,通过这些配置项来创建Retrofit对象。每个配置项的方法返回Builder对象,用于.来进行配置的连接,最后通过build方法创建Retrofit。
比如配置baseUrl:
public static final class Builder {
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
return baseUrl(HttpUrl.get(baseUrl));
}
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
List<String> pathSegments = baseUrl.pathSegments();
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
}
检测baseUrl是否为null,调用重载的baseUrl方法。baseUrl(HttpUrl baseUrl)中检测baseUrl是否为null,并且检测url是否合法,最后赋值给Builder对象的baseUrl。最后返回this。
build方法:
public static final class Builder {
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
......
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
}
通过此方法返回Retrofit对象。
这里先不进行配置项相关的说明,后面碰到会说明。
生成Java接口对象
获取接口对象时,是通过Retrofit的create方法。
public final class Retrofit {
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@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.adapt(okHttpCall);
}
});
}
}
首先调用Utils.validateServiceInterface方法验证service。
final class Utils {
static <T> void validateServiceInterface(Class<T> service) {
if (!service.isInterface()) {
throw new IllegalArgumentException("API declarations must be interfaces.");
}
if (service.getInterfaces().length > 0) {
throw new IllegalArgumentException("API interfaces must not extend other interfaces.");
}
}
}
此方法验证service是不是Java接口,并且验证接口是否继承了其他接口。
接着分析Retrofit的create的方法。通过变量validateEagerly来判断是否调用eagerlyValidateMethods方法,validateEagerly表示是否调用create方法时急切的验证接口中的方法的配置,默认是false。
接着是创建一个InvocationHandler匿名内部类对象,调用Proxy.newProxyInstance的方法来创建一个Java接口对象。这里使用了Java的动态代理的知识。一旦调用Java接口中的方法就会调用到InvocationHandler中的invoke方法。
总结:
Retrofit的create方法有两个功能,一是验证接口,一个是通过
Proxy.newProxyInstance方法生成一个动态代理的Java接口对象。
调用对象的方法获取Call
调用对象的方法会调用到InvocationHandler匿名对象的invoke方法。
Call<List<Repo>> repos = service.listRepos("octocat");
我们来分析一下InvocationHandler匿名内部对象的invoke方法。
public final class Retrofit {
public <T> T create(final Class<T> service) {
......
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override public Object invoke(Object proxy, Method method,
@Nullable Object[] args) throws Throwable {
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.adapt(okHttpCall);
}
});
}
}
invoke有三个参数,proxy是调用者对象,method调用的方法,args调用方法的参数。
首先调用method的getDeclaringClass获取声明类是不是Object,也就是判断是不是Object的方法,如果是直接调用方法。
然后调用Platform对象的isDefaultMethod。what?Platform什么?????先放一下。后面我们在分析。
最后是调用Retrofit的loadServiceMethod获取ServiceMethod对象,并且创建一个OkHttpCall对象,并调用OkHttpCall适配返回。
我们先来分析一下Platform
Platform
因为Retrofit支持Java平台和Android平台,而Platform就是对平台的抽象。使用单例设计模式。
class Platform {
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
......
}
使用的是饿汉式的单例设计方式。获取具体实现的对象是通过findPlatform方法。
class 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();
}
......
}
通过Class.formName获取相关的类,获取不到就会报异常,Android平台检测的是android.os.Build类,存在并且SDK的版本不等于0就返回Android。
Android类中的isDefault方法
static class Android extends Platform {
@Override boolean isDefaultMethod(Method method) {
if (Build.VERSION.SDK_INT < 24) {
return false;
}
return method.isDefault();
}
......
}
小于24版本直接返回false。大于等于24是调用的method的isDefault。isDefault是接口类型中定义的非静态非抽象的方法。
Notice:
Platform中有许多的默认配置。在创建Retrofit时,在Builder中也使用到了Platoform。
上面分析到了InvocationHandler的方法中
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
不满足因此会调用Retrofit的loadServiceMethod方法。
Retrofit的loadServiceMethod方法
public final class Retrofit {
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
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;
}
}
这里采用了双重检测。首先从缓存的Map获取ServiceMethod,第一次调用时是没有缓存的。然后进入synchronized块中再检测一次,如果还是不存在就使用ServiceMethod.Builder来创建ServiceMethod方法。然后放入缓存中。
ServiceMethod是一个很关键的类,所有的解析都在这里面呢。我接着分析ServiceMethod`类。
ServiceMethod
ServiceMethod也是通过Builder模式来创建的。只是很奇怪既然是Builder模式但是只有一个build方法,确没有相关的配置方法,未免有点鸡肋了。
static final class Builder<T, R> {
final Retrofit retrofit;
final Method method;
final Annotation[] methodAnnotations;
final Annotation[][] parameterAnnotationsArray;
final Type[] parameterTypes;
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
}
在Builder的构造方法中,关键是通过method获取方法的注解,获取参数的注解,以及参数的类型。
我们接着分析Builder的build方法。
ServiceMethod的Builder的build方法主要有五个步骤
- 调用
createCallAdapter方法创建CallAdapter,用于适配OkHttp中的Call。 - 调用
createResponseConverter方法创建Converter<ResponseBody, T>对象,用于转换ResponseBody到相应的对象。 - 循环调用
parseMethodAnnotation方法来解析方法的注解 - 循环调用
parseParameter方法解析方法的参数注解 - 创建
ServiceMethod对象
我们一步一步分析其功能。
获取CallAdapter对象
第一步是调用createCallAdapter方法来获取CallAdapter对象
static final class Builder<T, R> {
CallAdapter<T, R> callAdapter;
public ServiceMethod build() {
callAdapter = createCallAdapter();
......
}
}
通过createCallAdapter来获取callAdapter对象。
static final class Builder<T, R> {
CallAdapter<T, R> callAdapter;
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);
}
}
}
首先解析method的返回的类型,判断是否可以解析。然后获取方法的注解,并调用retrofit对象的callAdapter方法获取对象。
public final class Retrofit {
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
}
会调用Retrofit的nextCallAdapter方法。
public final class Retrofit {
final List<CallAdapter.Factory> callAdapterFactories;
public CallAdapter<?, ?> nextCallAdapter(
@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter =
callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
......
}
}
检测返回着类型,和方法的注解。传递的skipPase为null,因此遍历所有的callAdapterFactories通过get方法来获取到CallAdapter对象。
callAdapterFactories是在Retrofit.Builder中进行赋值的。在Builder中有两个地方进行添加的,一个是在
public static final class Builder {
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
callAdapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
public Retrofit build() {
......
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> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
}
}
第一个是通过addCallAdapter.Factory添加自己的CallAdapterFactory,第二个是通过获取通过platform获取Executor对象。然后通过defaultCallAdapterFactory获取CallAdapter.Factory对象。
我们分析平台为Android我们来看一下这两个函数返回什么内容。
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@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);
}
}
}
defaultCallbackExecutor返回的是主线程的Executor封装。defaultCallAdapterFactory返回的是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) {
......
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
}
ExecutorCallAdapterFactory的get方法中获取的CallAdapter对象,关键的是复写了adapte返回ExecutorCallbackCall。
Converter对象
第二步是在createResponseConverter来获取Converter对象。
static final class Builder<T, R> {
final List<CallAdapter.Factory> callAdapterFactories;
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);
}
}
}
此方法会调用Retrofit的responseBodyConverter获取Converter对象。
public final class Retrofit {
public <T> Converter<ResponseBody, T> responseBodyConverter(
Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
}
会调用Retrofit的nextCallAdapter方法。
public final class Retrofit {
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;
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;
}
}
......
}
}
检测方法的类型,检测方法的注解。我们传递的skipPast为null,因此循环converterFactories集合然后调用Factory的responseBodyConverter方法。最后返回判断是否遍历到了。
循环解析方法注解
第三步是循环调用parseMethodAnnotation方法解析注解。
static final class Builder<T, R> {
public ServiceMethod build() {
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
}
}
我们现在来分析一下parseMethodAnnotation方法。
static final class Builder<T, R> {
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.");
}
}
......
}
}
根据注解的类型进行相关的解析。限于篇幅的解析我们这里就不展开了。
解析方法参数注解
第四步是循环调用parseParameter来处理参数。
static final class Builder<T, R> {
public ServiceMethod build() {
int parameterCount = parameterAnnotationsArray.length;
//创建ParameterHandler数组
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
......
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
}
}
for循环中进行了很多判断我们这里省略。我们继续分析parseParameter方法。
static final class Builder<T, R> {
private ParameterHandler<?> parseParameter(
int p, Type parameterType, Annotation[] annotations) {
ParameterHandler<?> result = null;
for (Annotation annotation : annotations) {
ParameterHandler<?> annotationAction = parseParameterAnnotation(
p, parameterType, annotations, annotation);
if (annotationAction == null) {
continue;
}
if (result != null) {
throw parameterError(p, "Multiple Retrofit annotations found, only one allowed.");
}
result = annotationAction;
}
if (result == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
return result;
}
}
每个参数可以包含多个注解,这里循环调用parseParameterAnnotation进行解析。
static final class Builder<T, R> {
private ParameterHandler<?> parseParameterAnnotation(
int p, Type type, Annotation[] annotations, Annotation annotation) {
if (annotation instanceof Url) {
......
return new ParameterHandler.RelativeUrl();
......
} else if (annotation instanceof Path) {
return new ParameterHandler.Path<>(name, converter, path.encoded());
}
}
}
parseParameterAnnotation中的结构基本就是判断是否不是某个注解,然后返回相应的ParameterHandler中的类。
我们来看一下ParamterHandler的继承关系。
每个参数注解都会继承自ParameterHandler,用于处理参数。ParameterHandler关键方法是apply会设置相应的RequestBuilder的相应的网络参数。限于类过多这里只是列举了三个。
创建ServiceMethod对象
第五步就简单了。直接创建了
static final class Builder<T, R> {
public ServiceMethod build() {
......
return new ServiceMethod<>(this);
}
}
传递Builder对象来创建ServiceMethod对象。
创建OKHttpCall对象
public final class Retrofit {
public <T> T create(final Class<T> service) {
......
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override public Object invoke(Object proxy, Method method,
@Nullable Object[] args) throws Throwable {
......
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
}
我们已经分析了如何获取ServiceMethod对象。下面我们来看看如何创建OKhttpCall的,以及如何ServiceMethod如何适配OKHttpCall对象的。
final class OkHttpCall<T> implements Call<T> {
OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
}
OkHttpCall继承自Retrofit的Call接口,构造方法只是简单的赋值,serviceMethod变量为获取的ServiceMethod,args是方法的参数。
我们继续分析一下ServiceMethod的adapter方法。
final class ServiceMethod<R, T> {
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}
}
仅仅通过ServiceMethod的callAdapter适配。我们在获取CallAdapter对象一节adapt方法中封装Call为ExecutorCallbackCall。
通过Call进行网络请求
Call请求的基本流程
Call请求很复杂,但是基本都是简单的逻辑处理。我们一起来分析一下。
我们在调用对象的方法获取Call一节知道了Call返回的是ExecutorCallbackCall的对象,而ExecutorCallbackCall委托类是OkHttpCall。
我们从ExecutorCallbackCall开始。
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
@Override public void enqueue(final Callback<T> 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() {
......
}
});
}
......
});
}
}
enqueue方法中很简单,创建一个匿名的Callback内部类,内部类会调用callbackExecutor。callbackExecutor实际为Android类中的defaultCallbackExecutor方法返回的MainThreadExecutor对象(未在Retrofit.Builder设置的情况)。也就会把结果通知到主线程。
delegate对象实际是OkHttpCall对象,我们来分析一下OkHttpCall的enqueue方法。
OKHttpCall的主要功能有两个
- 创建okhttp3.Call,用于进行真实的网络请求。
- 调用okhttp3.Call的enqueue方法,然后对响应进行解析。
我们来一步一步进行解析。
final class OkHttpCall<T> implements Call<T> {
private @Nullable okhttp3.Call rawCall;
@Override public void enqueue(final Callback<T> callback) {
......
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 {
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
}
先判断executed是否已经执行过,执行过就抛出异常。
赋值rawCall到call,因为我们还没创建okhttp3.Call,因此为空,然后是尝试调动createRawCall。
我们来分析一下createRawCall方法。
final class OkHttpCall<T> implements Call<T> {
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = serviceMethod.toCall(args);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
}
调用ServiceMethod对象的toCall方法来获取okhttp3.Call。
final class ServiceMethod<R, T> {
okhttp3.Call toCall(@Nullable Object... args) throws IOException {
RequestBuilder requestBuilder =
new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
contentType, hasBody, isFormEncoded, isMultipart);
ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
int argumentCount = args != null ? args.length : 0;
if (argumentCount != handlers.length) {
throw new IllegalArgumentException("Argument count (" + argumentCount
+ ") doesn't match expected count (" + handlers.length + ")");
}
for (int p = 0; p < argumentCount; p++) {
handlers[p].apply(requestBuilder, args[p]);
}
return callFactory.newCall(requestBuilder.build());
}
}
创建一个RequestBuilder对象,然后比较参数的数量是否与参数处理器(ParameterHandler)的数量一致。不一致直接抛出异常。然后是循环调用ParameterHandler的apply来构建参数。
最后调用requestBuilder的build创建一个Request。并调用CallFactory的newCall来创一个okhttp3.Call并返回。okhttp3.Call.Factory可以通过Retrofit的Builder的下面的两个方法来定义自己的Factory
public static final class Builder {
public Builder client(OkHttpClient client) {
return callFactory(checkNotNull(client, "client == null"));
}
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = checkNotNull(factory, "factory == null");
return this;
}
}
至此我们创建了一个okhttp3.Call对象,
下面我们是进行网络请求。
final class OkHttpCall<T> implements Call<T> {
private @Nullable okhttp3.Call rawCall;
@Override public void enqueue(final Callback<T> callback) {
......
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
......
}
}
这里只列举类onResponse方法,没有列举出来onFailure方法。
在通过parseResponse来结果,根据结果调用相应的回调。我们一起来分析一下parseResponse方法
final class OkHttpCall<T> implements Call<T> {
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
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();
}
}
......
}
先获取code,判断是否是请求失败的错误码,如果是直接调用Response.error返回。
final class OkHttpCall<T> implements Call<T> {
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
......
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}
......
}
}
如果是204和205错误码直接返回。
final class OkHttpCall<T> implements Call<T> {
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
......
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
T body = serviceMethod.toResponse(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
catchingBody.throwIfCaught();
throw e;
}
}
}
调用ServiceMethod对象的toResponse解析,然后调用Response.success方法返回。
我们来看一下ServiceMethod的toResponse的方法。
final class ServiceMethod<R, T> {
private final Converter<ResponseBody, R> responseConverter;
R toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}
}
最后是通过Converter转化body到相应的类。
至此我们的分析基本完成了。
总结:
- 我们获取
Retrofit对象时,是通过Retrofit的Builder的构建,当未设置其他参数时,Platoform类会提供默认的设置 - 获取
Call对象的时候设计到Java代理,然后通过ServiceMethod对象接口的注解进行解析保存 - 调用
Call的时候会创建okhttp3.Call对象来进行网络请求,最后通过Convert转化body相应的对象。
结构设计
上面流程基本完成了,下面我们来看一下Retrofit的结构设计。
- Retrofit和Retrofit.Builder使用Facade模式封装底层的子系统,并且使用Builder模式来组织。
- ServiceMethod主要是因此解析注解参数,协调各个类的工作,有点类似中介者模式。
- ParameterHandler用于解析接口方法的参数
- CallAdapter适配Call到对应的类,相关的类的使用设计模式非常多,后面我们再分析
- Converter用于转化响应到对应的结构。
下面我们一一分析
Retrofit和Retrofit.Builder
Retrofit和Retrofit.Builder采用了Builder设计模式,让Retrofit对象的创建与使用相分离。通过不同的创建的步骤不同,Retrofit也不同。
同时Retrofit.Builder依赖Platform类,Platform与平台相关的类,Platform类使用了单例和抽象工厂。
Platform中创建了一组平台相关的默认的CallAdapter.Factory,Converter.Factory和回调的Executor。
Call相关的类设计
Call采用了装饰者模式,OkHttpCall实现了Call,而ExecutorCallbackCall则是装饰者,主要是增强的功能是回调的接口在相应的Executor中执行。Android中是主线程的Executor。
CallAdapter使用的是还有适配器模式和抽象工厂模式。
CallAdapter适配Call到对应的类。ExecutorCallAdapterFactory中CallAdapter的匿名内部类适配Call到ExecutorCallbackCall,DefaultCallAdapterFactory中的CallAdapter匿名内部类会直接返回Call,RxJava2CallAdapter会适配Call到Observable。
CallAdapter.Factory使用的是抽象工厂模式。用于创建CallAdapter。
Converter相关的类设计
Converter用于转化响应到相关的类。Converter.Factory与Converter采用了抽象工厂模式。BuiltnConverter中也封装了其他的转化器。