不忘初心 砥砺前行, Tomorrow Is Another Day !java
本文概要:设计模式
在分析Retrofit以前,咱们须要对基本的网络以及网络框架有个综合的对比认识.api
okHttp、urlConnection、httpClient、volley、retrofit之间的关系缓存
Retrofit的使用比较简单,基本是就是经过三类注解方法注解,参数注解. 这里就再也不讲述了,找了一篇我的感受比较全面的文章你真的会用Retrofit2吗?Retrofit2彻底教程进行参考学习.咱们重点进行原理分析.bash
源码版本2.5.0
Retrofit是经过动态代理的方式建立各类网络接口的代理.网络
关于动态代理,笔者另起了篇讲述.设计模式之代理模式若有兴趣的能够看一下.最后咱们回归正题.框架
使用过程通常都是经过建造者的build方法来构建Retorfit对象.咱们就从Retorfit对象的建立开始,异步
使用示例-1ide
mRetrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.callFactory(okHttpClient)
.build();
复制代码
直接看build方法的对应源码oop
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
// 1.初始化callFactory,若是未设置则默认设置一个OkHttpClient
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
// 2.初始化回调执行器,用于回调到UI线程
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// 3.初始化适配器工厂集合,添加一个默认适配器工厂(ExecutorCallAdapterFactory)
//用于适配返回类型,如默认支持的Call<T>
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// 4.初始化转换器集合
//用于网络响应的解析
List<Converter.Factory> converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
//...省略部分代码
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
复制代码
在build方法里,初始化时会经过platform对象添加一些默认的适配器,转换器,以及回调执行器.咱们看具体的添加操做.
对应源码
static class Android extends Platform {
@IgnoreJRERequirement // Guarded by API check.
@Override boolean isDefaultMethod(Method method) {
if (Build.VERSION.SDK_INT < 24) {
return false;
}
return method.isDefault();
}
//添加默认回调执行器
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
//添加默认的适配器工厂(ExecutorCallAdapterFactory)
@Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor);
return Build.VERSION.SDK_INT >= 24
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
@Override int defaultCallAdapterFactoriesSize() {
return Build.VERSION.SDK_INT >= 24 ? 2 : 1;
}
//添加默认的转换器工厂
@Override List<? extends Converter.Factory> defaultConverterFactories() {
return Build.VERSION.SDK_INT >= 24
? singletonList(OptionalConverterFactory.INSTANCE)
: Collections.<Converter.Factory>emptyList();
}
@Override int defaultConverterFactoriesSize() {
return Build.VERSION.SDK_INT >= 24 ? 1 : 0;
}
static class MainThreadExecutor implements Executor {
//绑定主线程的looper
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
//回调到主线程执行
handler.post(r);
}
}
}
复制代码
至此Retorfit对象建立过程就分析完了,作一个小结.
对于Retorfit的建立,进行一系列的初始化操做.
- 初始化callFactory
- 初始化"三器"
- 回调执行器,用于回调到UI线程
- 适配器工厂,用于适配返回的类型
- 转换器工厂,用于解析网络响应
Call的建立过程实质是网络接口的实现过程
Rerofit对象建立完成后,调用create方法时来实现咱们定义的网络接口ApiService,采用的就是动态代理.
使用示例-2
定义的网络接口类
public interface ApiService{
@GET
Observable<IDocViewBean> oaFileUpload(@Url String url,
@Query("token") String token,
@Query("mode") String mode,
@Query("url") String urlFile);
}
ApiService apiService = retrofit.create(ApiService.class);
复制代码
对应源码
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
/*
* 返回了网络接口的代理对象
*/
//当咱们调用代理对象的接口方法时,会触发InvocationHandler的invoke方法.
//如调用apiService.oaFileUpload(...)时,会完成oaFileUpload的实现,并返回一个Call<T>
//如调用apiService.oaFileUpload(...)时,会完成oaFileUpload的实现,并返回一个Call<T>
//如调用apiService.oaFileUpload(...)时,会完成oaFileUpload的实现,并返回一个Call<T>
//重要话说三遍,这一句理解了后面就容易了.
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);
}
//加载网络接口的方法,如加载oaFileUpload方法并调用.
/**
* 第一大步:先分析loadServiceMethod(method)获取到网络接口方法对象(ServiceMethod对象)
* 第二大步:调用ServiceMethod的invoke.
*/
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
复制代码
接着咱们看loadServiceMethod的具体实现
对应源码
ServiceMethod<?> loadServiceMethod(Method method) {
//先从缓存中获取.
ServiceMethod<?> result = serviceMethodCache.get(method);
//有缓存,直接返回.
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
//无缓存,对网络接口的方法进行解析,封装成ServiceMethod并添加进缓存.
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
复制代码
对网络接口的方法进行解析调用的了ServiceMethod.parseAnnotations,实际调用的是它的子类HttpServiceMethod.parseAnnotations方法.这里咱们直接看子类的方法.
对应源码
//HttpServiceMethod.java
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
//建立CallAdapter
CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);
Type responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError(method, "'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}
//建立转换器
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method) {
Type returnType = method.getGenericReturnType();
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
//里面经过retrofit对象的callAdapter方法获取CallAdapter对象
return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create call adapter for %s", returnType);
}
}
复制代码
createCallAdapter方法调用了retrofit对象的callAdapter方法获取CallAdapter对象.接着看retrofit的CallAdapter方法.
对应源码
//retrofit.java
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
//再接着往下看
return nextCallAdapter(null, returnType, annotations);
}
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;
//先遍历callAdapterFactories集合
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
//再经过网络接口的返回类型(returnType)来获取适配器工厂(CallAdapter.Factory),最终获取到CallAdapter对象.
//再经过网络接口的返回类型(returnType)来获取适配器工厂(CallAdapter.Factory),最终获取到CallAdapter对象.
//再经过网络接口的返回类型(returnType)来获取适配器工厂(CallAdapter.Factory),最终获取到CallAdapter对象.
//重要的话说三遍.
//因为以前在Retrofit对象建立阶段时,有默认设置CallAdapter.Factory为ExecutorCallAdapterFactory,那么遍历时就会获取到它.
//最后一块儿看下ExecutorCallAdapterFactory的get方法.
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
复制代码
//ExecutorCallAdapterFactory.java
@Override
public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
//检测返回类型是否是CALL
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
//返回一个CallAdapter对象,终于找到源头了,不容易啊.至此第一大步到此为止
return new CallAdapter<Object, Call<?>>() {
@Override
public Type responseType() {
return responseType;
}
//...省略部分代码
};
}
复制代码
调用ServiceMethod实际调用了HttpServiceMethod的invoke方法,咱们直接看这个方法.
//HttpServiceMethod.java
@Override ReturnT invoke(Object[] args) {
/*由于以前第一大步咱们已经清楚,默认状况下callAdapter是ExecutorCallAdapterFactory适配器工厂下返回的,
那么继续往下看适配器工厂找adapt
*/
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
//ExecutorCallAdapterFactory.java
public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
//...省略部分代码
@Override
public Call<Object> adapt(Call<Object> call) {
//返回的Call实际上就是ExecutorCallbackCall
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
复制代码
Call的建立过程相对来讲比较复杂,须要反复多浏览几遍,关键在于冷静下来根据线索去寻找.最后对Call的建立过程作一个总结.
- 当调用代理对象的网络接口方法时,会触发InvocationHandler的invoke方法,最终返回一个Call.
- 在invoke方法里面主要包含两大步骤.
- 第一大步,获取到网络接口方法对象(loadServiceMethod)
- 检查是否有缓存,有直接返回,无,从新解析生成新的对象后,缓存再返回
- 解析时获取适配器(CallAdapter),遍历适配器工厂集合,经过网络接口的返回类型(returnType)来获取对应适配器工厂,最终得到适配器(CallAdapter).
- 第二大步,调用ServiceMethod的invoke发送请求.
- 一样利用获取到的CallAdapter调用adapt方法,返回一个Call对象.最后发送请求.
最后咱们看ExecutorCallbackCall是如何发请求和回调的.
对应源码
static final class ExecutorCallbackCall<T> implements Call<T> {
//初始化时设置的线程回调执行器
final Executor callbackExecutor;
//为OkHttpCall
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
//发送网络请求
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {//使用okhttpClient进行异步请求
//网络回调成功
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
//主线程回调失败
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);
}
});
}
});
}
//...省略部分代码
}
复制代码
最后老规矩,对网络请求的发送过程作一个小结.
经过enqueue方法,利用Okhttp发送网络请求,网络响应成功或失败经过回调执行器(MainThreadExecutor)分发到主线程执行.
因为本人技术有限,若有错误的地方,麻烦你们给我提出来,本人不胜感激,你们一块儿学习进步.