移步Retrofit--网络通讯框架
Retrofit的工作
- 设置url的前半部分
- 生产平台适配器
Platform
- 通过Platform生成
MainThreadExecutor
和ExecutorCallAdapterFactory
- 通过外部添加数据转换器Converter.Factory
- 通过
create()
方法生成网络请求接口的代理
源码分析
1. Retrofit成员变量分析
public final class Retrofit {
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
//网络请求工厂,默认为OkHttpClient
final okhttp3.Call.Factory callFactory;
//请求url前半部,基地址
final HttpUrl baseUrl;
//数据转换器工厂集
final List<Converter.Factory> converterFactories;
//网络请求适配器工厂集
final List<CallAdapter.Factory> callAdapterFactories;
//请求结果线程切换执行器,默认是回到UI线程内
final @Nullable Executor callbackExecutor;
//标志位、是否马上解析接口方法
final boolean validateEagerly;
...
}
上面的这些成员变量最终都会通过建造者模式
Retrofit.build()
方法内的new Retrofit(...)
赋值
2. 内部类Builder源码分析
public Builder() {
this(Platform.get());
}
Builder(Platform platform) {
this.platform = platform;
}
Platform会单独分析,这里只知道Platform可以生成MainThreadExecutor
和ExecutorCallAdapterFactory
。
- MainThreadExecutor是回调到Ui线程的执行器
- ExecutorCallAdapterFactory是网络请求适配器,可以生成最后交付给用户使用的Call对象。ExecutorCallAdapterFactory也会单独分析。
3. Build.build()源码分析
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//默认为空,初始化为OkHttpClient
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//获取回调执行器,如果没有则通过Platform创建一个主线程回调执行器
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
//设置CallAdapter.Factory列表
//我们可以通过addCallAdapterFactory()方法加入我们自己的adapter,例如rxjava2的callAdapter,
//系统会在其后加入一个默认的Adapter,一旦用户没有指定适配器就使用默认的,Android使用ExecutorCallAdapterFactory
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
//设置Converter.Factory列表
//与上面不同的是,这次首先加入一个默认的,然后才加入用户设定的,上面是先添加用户的,然后添加默认的。
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size());
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
//实例化Retrofit
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
4. Retrofit#loadServiceMethod(),获取网络请求接口的ServiceMethod
//存取ServiceMethod
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache =
new ConcurrentHashMap<>();
ServiceMethod<?, ?> loadServiceMethod(Method method) {
//从缓存中取ServiceMethod
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;
}
ConcurrentHashMap是HashMap的一个线程安全的、支持高效并发的版本
通过retrofit和method(网络请求接口方法)创建网络请求接口方法解析对象,具体的操作会在ServiceMethod中详细分析
5. Retrofit#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, @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);
}
//方法 1
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
//方法 2
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//方法 3
return serviceMethod.adapt(okHttpCall);
}
});
}
接口调用方法进行网络请求时实际上会进入代理对象的invoke回调方法内,主要的操作也是如注释中的
方法1 2 3
- 方法1 获取接口方法对应的方法解析对象ServiceMethod
- 方法2 是通过Service和方法参数生成新的OkHttpCall(真正做网络操作的地方),OkHttpCall会单独分析
- 方法3 是通过ServiceMethod获取最终交付给用户的Call请求对象
网友评论