有一段时间没分享源码的东西了,最近两天有时间,顺便看下Retrofit源码,一是为了完善原来的理解,二是跟大家分享有理解偏差的地方希望大家批评。Retrofit火了很长时间了,刚开始问世时就在自己的网络请求模块引入使用,一晃好几年了,哈哈。
我们直接从我们平时的项目配置开始
val client = okHttpClient
.addInterceptor(interceptor)
.cache(Cache(File(App.instance.getCacheDir(), "cache"), 1024 * 1024 * 10)) // 缓存设置
.addNetworkInterceptor(mRewriteCacheControlInterceptor) // 网络设置
.retryOnConnectionFailure(true) // 连接失败时尝试重连
.build()
val builder = Retrofit.Builder() // 使用变种Buidler模式构建对象
.baseUrl(HttpMethod.ROOT_API_URL) // 基础url
.client(client)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 利用工厂模式添加CallAdapter
return builder
.addConverterFactory(GsonConverterFactory.create()) // 利用工厂模式添加解析方式
.build()
Retrofit的精巧之处就在于它使用了大量的设计模式来进行解耦,刚开始使用时可能感觉还很不适应,但后续在了解了它或添加其他细化功能时你就感觉了它的强大。
首先构建对象采用使用很广泛的Builder模式,
public Builder() {
this(Platform.get());
}
public Retrofit build() {
if (this.baseUrl == null) { // 必须配置baseUrl
throw new IllegalStateException("Base URL required.");
} else {
Factory callFactory = this.callFactory;
if (callFactory == null) { // 默认使用OkHttp进行网络请求
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) { // callbackExecutor如果未设置会使用默认值赋值
callbackExecutor = this.platform.defaultCallbackExecutor();
}
List<retrofit2.CallAdapter.Factory> adapterFactories = new ArrayList(this.adapterFactories);
adapterFactories.add(this.platform.defaultCallAdapterFactory(callbackExecutor));
List<retrofit2.Converter.Factory> converterFactories = new ArrayList(this.converterFactories);
return new Retrofit((Factory)callFactory, this.baseUrl, converterFactories, adapterFactories, callbackExecutor, this.validateEagerly);
}
}
buidler方法没设么特别的地方,只是做了一些初始化的动作,如果用户未做定制化的东西就赋予默认值。但这里需要留意一下Buidler构造里的Platform。默认情况下时使用的是其返回的值。
static class Android extends Platform {
Android() {
}
public Executor defaultCallbackExecutor() {
return new Platform.Android.MainThreadExecutor();
}
Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) {
throw new AssertionError();
} else {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
MainThreadExecutor() {
}
public void execute(Runnable r) {
this.handler.post(r);
}
}
}
最终调用的代码即callbackExecutor的默认值为Platform下的Android类代码。
下面我们来看下一步,create方法
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (this.validateEagerly) { // 手动设置了validateEagerly会触发此函数
this.eagerlyValidateMethods(service);
}
// 使用动态代理模式以及后续处理一系列解析及配置网络请求操作
return Proxy.newProxyInstance(service.getClassLoader(), new Class[]{service}, new InvocationHandler() {
// 获取所在平台java8、android等
private final Platform platform = Platform.get();
public Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable {
// Object方法
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
} else if (this.platform.isDefaultMethod(method)) {
// java8的方法
return this.platform.invokeDefaultMethod(method, service, proxy, args);
} else {
// android平台的关键代码在这
ServiceMethod<Object, Object> serviceMethod = Retrofit.this.loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
}
});
}
invoke里主要做了一些平台的判断,我们直接来看android最关键的几行代码
ServiceMethod<Object, Object> serviceMethod = Retrofit.this.loadServiceMethod(method); // 创建serviceMethod对象,这是个最关键的类,Retrofit的一系列操作都通过它,但是在新版的Retrofit中遵循单一责任原则等做了解耦抽取。
OkHttpCall<Object> okHttpCall = new OkHttpCall(serviceMethod, args); // 请求回调构建
return serviceMethod.callAdapter.adapt(okHttpCall); // 适配adapter并开始请求及后续步骤
先来看下loadServiceMethod
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = (ServiceMethod)this.serviceMethodCache.get(method);
// 缓存中有直接获取
if (result != null) {
return result;
} else {
Map var3 = this.serviceMethodCache;
synchronized(this.serviceMethodCache) {
result = (ServiceMethod)this.serviceMethodCache.get(method);
if (result == null) {
// 缓存没有事通过Builder模式创建实例
result = (new retrofit2.ServiceMethod.Builder(this, method)).build();
this.serviceMethodCache.put(method, result);// 放入缓存
}
return result;
}
}
}
接着整,追踪到ServiceMethod
public ServiceMethod build() {
this.callAdapter = this.createCallAdapter(); // 从Rrofit获取CallAdapter
this.responseType = this.callAdapter.responseType(); // 从adapter获取返回的类型
if (this.responseType != Response.class && this.responseType != okhttp3.Response.class) {
this.responseConverter = this.createResponseConverter(); // 获取转换器类型
Annotation[] var1 = this.methodAnnotations;
int p = var1.length;
for(int var3 = 0; var3 < p; ++var3) {
Annotation annotation = var1[var3];
// 解析url等等注解信息
this.parseMethodAnnotation(annotation);
}
if (this.httpMethod == null) {
throw this.methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
} else {
if (!this.hasBody) {
if (this.isMultipart) {
throw this.methodError("Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (this.isFormEncoded) {
throw this.methodError("FormUrlEncoded can only be specified on HTTP methods with request body (e.g., @POST).");
}
}
int parameterCount = this.parameterAnnotationsArray.length;
this.parameterHandlers = new ParameterHandler[parameterCount];
for(p = 0; p < parameterCount; ++p) {
Type parameterType = this.parameterTypes[p];
if (Utils.hasUnresolvableType(parameterType)) {
throw this.parameterError(p, "Parameter type must not include a type variable or wildcard: %s", parameterType);
}
Annotation[] parameterAnnotations = this.parameterAnnotationsArray[p];
if (parameterAnnotations == null) {
throw this.parameterError(p, "No Retrofit annotation found.");
}
// 解析注解参数等信息
this.parameterHandlers[p] = this.parseParameter(p, parameterType, parameterAnnotations);
}
......
// 一些解析参数的容错提示
return new ServiceMethod(this);
}
}
} else {
......
// 一些解析参数的容错提示
}
}
我们继续看下解析url及方法名注解和参数注解两个方法
private void parseMethodAnnotation(Annotation annotation) {
if (annotation instanceof DELETE) {
this.parseHttpMethodAndPath("DELETE", ((DELETE)annotation).value(), false);
} else if (annotation instanceof GET) {
this.parseHttpMethodAndPath("GET", ((GET)annotation).value(), false);
}
........
}
private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) {
if (this.httpMethod != null) {
throw this.methodError("Only one HTTP method is allowed. Found: %s and %s.", this.httpMethod, httpMethod);
} else {
this.httpMethod = httpMethod;
this.hasBody = hasBody;
// 匹配注解方法中的值如:users/{user}/repos or user
if (!value.isEmpty()) {
int question = value.indexOf(63);
if (question != -1 && question < value.length() - 1) {
String queryParams = value.substring(question + 1);
Matcher queryParamMatcher = ServiceMethod.PARAM_URL_REGEX.matcher(queryParams);
if (queryParamMatcher.find()) {
throw this.methodError("URL query string \"%s\" must not have replace block. For dynamic query parameters use @Query.", queryParams);
}
}
// 赋值url及其中参数
this.relativeUrl = value;
this.relativeUrlParamNames = ServiceMethod.parsePathParameters(value);
}
}
}
private ParameterHandler<?> parseParameter(int p, Type parameterType, Annotation[] annotations) {
ParameterHandler<?> result = null;
Annotation[] var5 = annotations;
int var6 = annotations.length;
for(int var7 = 0; var7 < var6; ++var7) {
Annotation annotation = var5[var7];
ParameterHandler<?> annotationAction = this.parseParameterAnnotation(p, parameterType, annotations, annotation);
if (annotationAction != null) {
if (result != null) {
throw this.parameterError(p, "Multiple Retrofit annotations found, only one allowed.");
}
result = annotationAction;
}
}
if (result == null) {
throw this.parameterError(p, "No Retrofit annotation found.");
} else {
return result;
}
}
parseParameterAnnotation方法太长这里就不粘了,就是根据不同类型解析对应参数,我们挑选其中一种简单看下
if (annotation instanceof Query) {
// 获取Query相应值及参数 value、编码、基础类型等等
Query query = (Query)annotation;
partName = query.value();
encoded = query.encoded();
arrayComponentType = Utils.getRawType(type);
this.gotQuery = true;
if (Iterable.class.isAssignableFrom(arrayComponentType)) {
// 通过三种状态包括可迭代Iterable、Array、其他。最后组装成ParameterHandler供后续网络请求使用。
if (!(type instanceof ParameterizedType)) {
throw this.parameterError(p, arrayComponentType.getSimpleName() + " must include generic type (e.g., " + arrayComponentType.getSimpleName() + "<String>)");
} else {
parameterizedType = (ParameterizedType)type;
iterableType = Utils.getParameterUpperBound(0, parameterizedType);
converter = this.retrofit.stringConverter(iterableType, annotations);
return (new retrofit2.ParameterHandler.Query(partName, converter, encoded)).iterable();
}
} else if (arrayComponentType.isArray()) {
arrayComponentType = ServiceMethod.boxIfPrimitive(arrayComponentType.getComponentType());
valueConverter = this.retrofit.stringConverter(arrayComponentType, annotations);
return (new retrofit2.ParameterHandler.Query(partName, valueConverter, encoded)).array();
} else {
converter = this.retrofit.stringConverter(type, annotations);
return new retrofit2.ParameterHandler.Query(partName, converter, encoded);
}
}
好ServiceMethod的创建及缓存已经完成,接下来是:
OkHttpCall<Object> okHttpCall = new OkHttpCall(serviceMethod, args);
从名字很容易想到OkHttp的Call,是的!他就是OkHttp的封装!我们这里指摘取他的异步方法看下。
public void enqueue(final Callback<T> callback) {
Utils.checkNotNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized(this) { // 加锁
if (this.executed) {
throw new IllegalStateException("Already executed.");
}
this.executed = true; // 是否已执行
call = this.rawCall; // 赋值rawCall用于复用
failure = this.creationFailure;
if (call == null && failure == null) {
try {
call = this.rawCall = this.createRawCall(); // 这句比较关键,也是能抓出他就是OkHttpCall封装的证据
} catch (Throwable var7) {
failure = this.creationFailure = var7;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
} else {
if (this.canceled) {
call.cancel();
}
// 开始执行异步操作并接回回执
call.enqueue(new okhttp3.Callback() {
public void onResponse(okhttp3.Call call, Response rawResponse) throws IOException {
retrofit2.Response response;
try {
response = OkHttpCall.this.parseResponse(rawResponse);
} catch (Throwable var5) {
this.callFailure(var5);
return;
}
this.callSuccess(response);
}
public void onFailure(okhttp3.Call call, IOException e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable var4) {
var4.printStackTrace();
}
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable var3) {
var3.printStackTrace();
}
}
private void callSuccess(retrofit2.Response<T> response) {
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable var3) {
var3.printStackTrace();
}
}
});
}
}
private okhttp3.Call createRawCall() throws IOException {
Request request = this.serviceMethod.toRequest(this.args);
// 这里的call是在Retrofit创建时Builder的builde方法里OkHttpClient构造的
okhttp3.Call call = this.serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
} else {
return call;
}
}
到此为止还没有出发调用的地方,真相就在我们接下来要看的这句代码了
serviceMethod.callAdapter.adapt(okHttpCall);
这里要结合两点:
第一点我们要知道ServiceMethod中的build方法中创建的callAdapter最终调用到了Rerofit中的
public CallAdapter<?, ?> nextCallAdapter(@Nullable retrofit2.CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
Utils.checkNotNull(returnType, "returnType == null");
Utils.checkNotNull(annotations, "annotations == null");
int start = this.adapterFactories.indexOf(skipPast) + 1;
int i = start;
int i;
for(i = this.adapterFactories.size(); i < i; ++i) {
//最关键的代码,调用实现该方法地方的get处
CallAdapter<?, ?> adapter = ((retrofit2.CallAdapter.Factory)this.adapterFactories.get(i)).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
// 错误信息展示
StringBuilder builder = (new StringBuilder("Could not locate call adapter for ")).append(returnType).append(".\n");
if (skipPast != null) {
builder.append(" Skipped:");
for(i = 0; i < start; ++i) {
builder.append("\n * ").append(((retrofit2.CallAdapter.Factory)this.adapterFactories.get(i)).getClass().getName());
}
builder.append('\n');
}
builder.append(" Tried:");
i = start;
for(int count = this.adapterFactories.size(); i < count; ++i) {
builder.append("\n * ").append(((retrofit2.CallAdapter.Factory)this.adapterFactories.get(i)).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}
篇幅有点长了,这里我们看其中的一种实现,就是默认的实现。这也是我们要结合的第二点:还记得
Platform中的Android实现类吗?就是它将线程调度到主线程并返回了所需的Executor。第一点中的get方法其实就是调用到了其中的
ExecutorCallAdapterFactory类的get方法
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
} else {
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
public Type responseType() { // 返回类型
return responseType;
}
public Call<Object> adapt(Call<Object> call) { // 执行方法
return new ExecutorCallAdapterFactory.ExecutorCallbackCall(ExecutorCallAdapterFactory.this.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;
}
// 真正的的调用处
public void enqueue(final Callback<T> callback) {
Utils.checkNotNull(callback, "callback == null");
// 用户真正传入的callback,delegate就是刚才传入的okHttpCall
this.delegate.enqueue(new Callback<T>() {
public void onResponse(Call<T> call, final Response<T> response) {
ExecutorCallbackCall.this.callbackExecutor.execute(new Runnable() {
public void run() {
if (ExecutorCallbackCall.this.delegate.isCanceled()) {
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
public void onFailure(Call<T> call, final Throwable t) {
ExecutorCallbackCall.this.callbackExecutor.execute(new Runnable() {
public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
好了到这,整个流程就连贯起来了。RxJava2CallAdapterFactory也是实现了这一套与之类似。