Retrofit2源码解析
- Retrofit实际上是一个网络请求框架的封装,它的核心是使用OkHttp来进行网络请求。
- 完成OkHttp数据的转化和适配工作
- Retrofit使用了动态代理
八个步骤
- 创建retrofit实例
- 定义网络请求接口,并添加注解
- 通过 动态代理 生成网络请求对象
- 通过 网络请求适配器 将网络请求对象 进行平台适配
- 通过 网络请求执行器(Call) 发送网络请求
- 通过 数据转换器 解析数据
- 通过 回调执行器 切换线程
- 在主线程处理返回结果
Method,ServiceMethod
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 Executor callbackExecutor;
final boolean validateEagerly;
- Method就是网络请求的接口,ServiceMethod是解析接口上的注解后的实际网络请求方法,在Retrofit中用LinkedHashMap对ServiceMethod进行了缓存
public static final class Builder {
private final Platform platform;
private okhttp3.Call.Factory callFactory;
private HttpUrl baseUrl;
private final List<Converter.Factory> converterFactories = new ArrayList<>();
private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
private Executor callbackExecutor;
private boolean validateEagerly;
callbackExecutor
默认的回调执行器是采用handler.post的方式让回调在主线程中执行。
public static final class Builder {
private final Platform platform;
private okhttp3.Call.Factory callFactory;
private HttpUrl baseUrl;
private final List<Converter.Factory> converterFactories = new ArrayList<>();
private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
private Executor callbackExecutor;
private boolean validateEagerly;
Call
Retrofit中的Call对象跟Client的Call对象不一样,前置进行了封装。
Retrofit:
//An invocation of a Retrofit method that sends a request to a webserver and returns a response.
public interface Call<T> extends Cloneable {
Response<T> execute() throws IOException;
void enqueue(Callback<T> callback);
boolean isExecuted();
void cancel();
boolean isCanceled();
Call<T> clone();
Request request();
}
OkHttp:
Converter
数据转换器,将返回的Response解析成一个Bean对象
CallAdapter
将Call接口适配成其他接口
源码分析
从create开始,它帮我们实例化了我们的服务端接口:
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);//验证
if (validateEagerly) {
//提前解析加载ServiceMethod,相当于缓存
eagerlyValidateMethods(service);
}
//返回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 {
// 如果调用的是Object类的方法,则直接调用就行了
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//从缓存中取出ServiceMethod
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//把Call交给CallAdapter适配
return
serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
这个Create实际上返回的是一个动态代理对象,当接口方法被调用时,会被动态代理拦截,然后调用InvocationHandler里的invoke方法,其中method就是调用的方法,args就是方法参数。
InvocationHandler会根据调用的接口里的方法,在缓存中取出解析后的ServiceMethod,然后构建一个OkHttpCall,最后交给CallAdapter进行适配,也就是将接口默认的方法返回值Call适配成其他类,比如RxJava的Observable。
对ServiceMethod进行了缓存:
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;
}