retrofit源码阅读记录 - Xiasm/Java-Android-Learn GitHub Wiki
retrofit源码没有多少,并且它的网络请求实现是用的okhttp,所以大体上的感觉就是它是在okhttp的基础上封装了一层,封装了什么呢?下面我们就来看一下它的源码吧!retrofit用到了动态代理和okhttp,关于这两个东西本文不再讲述,如果不知道的可以查些资料。
先来看下Retrofit使用方式:
public interface Api {
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
}
//标注1
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BuildConfig.baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(HttpSettings.commonOkHttpClient())
.build();
//标注2
Api api = retrofit.create(Api.class);
api.groupList(1).enqueue(callback);
标注1处代码就是通过构建者模式获取一个Retrofit实例,没有什么可说的。直接看标注2处,通过retrofit实例的create方法拿到一个Api对象,调用api的方法就可以请求并处理结果了。
直觉上,你是不是感觉到了什么?Api就是一个接口,为什么拿到这个接口的实例就能调用它的方法了呢?所以呢。肯定有一个代理对象偷偷对这个方法所了些东西。好了,奥妙就在create()方法,看代码:
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();
@Override public Object invoke(Object proxy, Method method, 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 serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
看到这个方法,你是否明白了?对,retrofit内部就是用的动态代理去实现了Api里方法调用的处理。直接看InvocationHandler的实现:
private final Platform platform = Platform.get();
上面这句代码就是得到一个平台相关的东西,看内部实现:
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {
try {
//标注1
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) {
}
try {
Class.forName("org.robovm.apple.foundation.NSObject");
return new IOS();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
可以看出,对于我们Android来说获取Platform肯定是走到标注1处了。我们来看看这个Android是干嘛的?
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
//标注1
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
接着看标注1,MainThreadExecutor内部维护了一个Handler,这个handler拿的是主线程的looper,所以大概能猜出来这个platform就是用来将要执行的东西切换到主线程的。用过okhttp的同学肯定知道,okhttp的网络请求回调是在工作线程,就是线程池里的线程,所以我们用okhttp的时候一般会将子线程的回调切换到主线程然后执行更新ui的操作。所以这个platform的职责就是将子线程的回调切换到主线程。看完了Platform,接着看InvocationHandler中invoke方法的实现:
@Override public Object invoke(Object proxy, Method method, 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 serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
我们知道,动态代理中调用被代理对象的方法实现就是这个invoke了,首先第一个if判断肯定不满足,第二个if判断的返回值对Android来说默认的就是false,直接往下看:
ServiceMethod serviceMethod = loadServiceMethod(method);
这个method就是我们要代理的method,在这里肯定就是下面方法了:
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
进入loadServiceMethod(method)内部:
ServiceMethod loadServiceMethod(Method method) {
ServiceMethod result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
serviceMethodCache就是一个方法的缓存,因为我们的Api的方法可能不止调用一次,所以对他的方法做了缓存,所以我们直接看这一行 result = new ServiceMethod.Builder(this, method).build();通过构建者模式创建了一个ServiceMethod,那么ServiceMethod是什么呢?看源码:
final class ServiceMethod<T> {
//...
static final class Builder<T> {
public Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
public ServiceMethod build() {
//标注1
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?");
}
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);
}
}
}
可以看出,Builder内部将method的注解、参数等等解析好然后创建出ServiceMethod,所以一个ServiceMethod里面就存储了请求接口的url、参数等等有用的信息,有一个地方需要我们注意,就是bulid()方法内部的标注1处:创建了一个CallAdapter,我们看createCallAdapter()方法:
private CallAdapter<?> 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 {
return 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);
}
}
public CallAdapter<?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = adapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
//...
throw new IllegalArgumentException(builder.toString());
}
createCallAdapter()方法内部将method的注解和返回值类型拿到之后,调用了Retrofit的callAdapter,最终调用到Retrofit的nextCallAdapter方法,nextCallAdapter()方法会从adapterFactories里面去寻找callAdapter,如果没找到,最后会抛出异常。所以这个adapterFactories肯定是在api的方法调用钱就初始化好了,不然肯定抛异常,我们看下它在哪里初始化的:
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
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的构造方法里传过来的,大家还记得上面Retrofit是通过Builder创建的,我们看一下Retrofit.Builder的build()方法:
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//标注1
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
//标注2
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
这个build()方法里可谓是Retrofit实例创建大揭秘,看标注2处就是adapterFactories创建,并且默认加入了一个platform的callAdapter,这个platform是怎么来的呢?看标注1,这里判断callbackExecutor为空就创建一个平台默认的callbackExecutor,我们上面看了Platform的源码,在Platform类加载的时候就会调用findPlatform()方法,最后是创建了一个Android类,这个Android是继承自Platform的,所以标注1处如果我们在创建Retrofit的时候没有指定callbackExecutor,就会默认创建一个Android platform,则我们的callbackExecutor和callAdapterFactory就是下面这俩:
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
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);
}
}
}
到这里我们明白了callAdapter是如何创建的,也将Platform和Retrofit联系起来了,我们重新回到Retrofit的create()方法的InvocationHandler里
@Override public Object invoke(Object proxy, Method method, 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 = loadServiceMethod(method);
//标注2
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
看标注1,现在我们创建了ServiceMethod,到这里你已经知道这个ServiceMethod的大致职责了吧,它就是保存了method的一些信息等,然后看标注2,创建了一个OkHttpCall,这个OkHttpCall内部封装了okhttp请求相关的东西,然后将serviceMethod的callAdapter和okhttpCall关联了起来。我们已经知道serviceMethod的callAdapter就是Android的defaultCallAdapterFactory(),也就是ExecutorCallAdapterFactory。好了,我们先不管ExecutorCallAdapterFactory,到这里我们先来理一下思路,首先通过Retrofit的create()方法,创建了一个动态代理的对象,代理的是Api,然后我们拿到这个api,调用api里面的方法,这个方法就会被代理,也就走到了create()方法内部的invoke()方法里面,执行代理方法。而我们在invoke里就是拿到api的method相关的注解参数等封装成serviceMethod,然后创建一个okhttp请求相关的OkHttpCall,将两者关联起来,最后调用serviceMethod.callAdapter.adapt(okHttpCall)并返回,所以最后 return serviceMethod.callAdapter.adapt(okHttpCall) 就是代理方法返回的结果。这个结果实际上就是我们Api的的方法的返回值:Call<List>。
这个返回值通过serviceMethod.callAdapter.adapt(okHttpCall)得到,我们已经知道callAdapter实际上就是ExecutorCallAdapterFactory,看它的adapt()方法:
@Override public <R> Call<R> adapt(Call<R> 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) {
if (callback == null) throw new NullPointerException("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();
}
}
最终的ExecutorCallbackCall通过构造方法传入OkHttpCall,将所有的网络请求都交给OkHttpCall处理。