源码分析基于 2.7.0
https://juejin.cn/post/7094831913109717023/
主要分析了Retrofit如何运用动态代理生成代理对象以及请求如何生成。
Retrofit如何发起请求
1. 构建请求
前面分析我们得知,loadServiceMethod(method)返回HttpServiceMethod.CallAdapted,看下他的invoke函数做了什么
//HttpServiceMethod类中
@Override final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);//1
return adapt(call, args);//调用下面的adapt
}
//CallAdapter类中
@Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call);//2
}
//DefaultCallAdapterFactory类中
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
} else if (!(returnType instanceof ParameterizedType)) {
throw new IllegalArgumentException("Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
} else {
final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType)returnType);
final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class) ? null : this.callbackExecutor;
return new CallAdapter<Object, Call<?>>() {
public Type responseType() {
return responseType;
}
public Call<Object> adapt(Call<Object> call) {//3
return (Call)(executor == null ? call : new DefaultCallAdapterFactory.ExecutorCallbackCall(executor, call));
}
};
}
}
- 注释1:构建OkHttpCall对象,它的父类是retrofit2.Call,注意它封装了请求的参数;
- 注释2:callAdapter是适配返回值的对象,前面的文章分析知道,在没有设置CallAdapterFactory的情况下,DefaultCallAdapterFactory是默认的callAdapter提供者,也就是callAdapter对象是从DefaultCallAdapterFactory.get函数得到的;
- 注释3:注释2其实是触发返回ExecutorCallbackCall对象,它的父类也是retrofit2.Call;
- **至此,我们知道loadServiceMethod(method).invoke得到ExecutorCallbackCall对象,它封装了OkHttpCall,间接封装了请求参数;
2.发起请求
我们知道发起请求,就是调用Call的enqueue函数,它的真正类型是ExecutorCallbackCall维护成员变量OkHttpCall;
//ExecutorCallbackCall类中
@Override public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
......
delegate.enqueue();//1 调用下面的enqueue函数
......
}
//OkHttpCall类中
@Override public void enqueue(final Callback<T> callback) {
if (executed) throw new IllegalStateException("Already executed.");//同一个call只能执行一次
executed = true;
......
call = rawCall = createRawCall();//2
......
call.enqueue(new okhttp3.Callback() {//3
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response = parseResponse(rawResponse);//4
......
callback.onResponse(OkHttpCall.this, response);
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
callback.onFailure(OkHttpCall.this, e);//5
}
});
}
- 注释1:delegate是OkHttpCall,这里有点代理设计模式的味道;
- 注释2:将参数、函数注解、参数值封装成真正发起请求的Call,类型okhttp3.Call,;
- 注释3:终于走到OKhttp的代码了,发起请求;
- 注释4:利用构建OkHttpCall时传入的结果解析器解析成Bean,并返回;
- 注释5:回调失败;
- 注意,这里的回调都是回到了ExecutorCallbackCall类中,它再回调给真正的调用者;
//ExecutorCallbackCall类中,
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(() -> {//1
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(() -> callback.onFailure(ExecutorCallbackCall.this, t));
}
});
- 注释1:利用构建ExecutorCallbackCall传入的callbackExecutor回调执行器进行线程切换,默认切换会主线程;
- 至此,使用Retrofit发起网络请求流程已完成。
大体流程
插件化流程 (4).png为什么要使用两层代理呢?
还是分层思想,ExecutorCallbackCall有一个很重要的任务,就是回调切换线程;
而OkHttpCall更多负责请求、解析结果;而okhttp3.Call才是真正发起请求的;
总结
- 使用静态代理模式发情网络请,ExecutorCallbackCall代理OkHttpCall,后者代理okhttp3.Call完成发起网络请求;
- 使用回调执行器将结果回到主线程;
以上分析有不对的地方,请指出,互相学习,谢谢哦!
网友评论