Retrofit 是当下android开发最流行的网络请求框架。用了Retrofit体会到了它的强大之处一直对它的内部实现很感兴趣,花了两天的时间研究了一下它的源码,虽然对里面的设计模式,和为什么要这么做说不出个所以然来,但还是把Retrofit的整个流程搞清楚了。接下来就是记录了一下解析的过程。尽量的写详细点.........
一、retrofit的创建源码解析
众所周知retrofit的创建是用builder模式创建的,最后就是初始化Retrofit里面所需要的成员对象:一个callFactory其实就是OkHttpClient;还有两个factory容器,这里就是工厂模式,分别用来生产解析请求结果(Json数据),和适配网络求情的CallAdapter.
Retrofit(okhttp3.Call.Factory callFactory, BaseUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = converterFactories;
this.adapterFactories = adapterFactories;
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
按照源码注释来使用Retrofit就是:
For example,
<pre>{@code
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.example.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
MyApi api = retrofit.create(MyApi.class);
Response<User> user = api.getUser().execute();
}</pre>
可以看到创建一个retrofit一般只需要在builder里传入baseUrl和一个GsonConverterFactory因为其他的参数都有默认值,如果不修改就采用默认值了。而且默认值都是在在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();
}
// Make a defensive copy of the adapters and add the default Call adapter.默认的含有CallAdapter。Factory的容器
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(Platform.get().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);
}
看,除了一个baseUrl必传入之外,其它的参数要么有默认的初始化要么可以不用传值:
- okhttp3.Call.Factory callFactory 可以猜到这个是用来进行网络请求的,如果不传入的话,默认的也是用 new OkHttpClient() 来进行初始化;
- List<CallAdapter.Factory> adapterFactories在Build里申明的时候就已经初始化为一个ArrayList,Bulid在设置CallAdapter的时候只是向里面添加CallAdapter,并且里面一开始就添加了默认的CallAdapterFactory:一个DefaultCallAdapterFactory的对象
/**
* Add a call adapter factory for supporting service method return types other than {@link
* Call}.
*/
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
adapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
所以Retrofit应该可以支持多个CallAdapter,这个在后面解析过程中再看是用来做什么的吧!
- 最后是List<Converter.Factory> converterFactories 其实也和List<CallAdapter.Factory> adapterFactories 一样,不过没有往里面加入默认值(猜一下它的作用:它是用来解析Json用的吧)。所以创建一个Retrofit至少就要用:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.example.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
- 最后的是一个boolean 值:validateEagerly(java中boolean的值都是false,当然也可以不用我们去初始化), 看一下代买的英文注释:
/**
* When calling {@link #create} on the resulting {@link Retrofit} instance, eagerly validate
* the configuration of all methods in the supplied interface.
*/
翻译过来就是 :创建完Retrofit的实例后,当去调用它的create方法时,一开始就(急切的)让这个接口(最后的Service)的方法变得合法化(不管你后面的代理对象能不能创建成功)。(个人理解)还是不懂请看下文
二、Retrofit的使用源码解析
创建好了Retrofit,那我们当然是要调用它的Api了,其实它的Api也就一个:<T> T create(final Class<T> service),就是这个方法。它的作用就是用动态代理模式,产生一个代理对象,可以用这个代理对象替我们完成网络请求,并返回结果。看看代码是怎么写的吧:
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);
}
return loadMethodHandler(method).invoke(args);
}
});
}
1、判断service类型
一进入这个方法里首先会对service的类型做判断: Utils.validateServiceInterface(service);
static <T> void validateServiceInterface(Class<T> service) {
if (!service.isInterface()) {
throw new IllegalArgumentException("API declarations must be interfaces.");
}
// Prevent API interfaces from extending other interfaces. This not only avoids a bug in
// Android (http://b.android.com/58753) but it forces composition of API declarations which is
// the recommended pattern.
if (service.getInterfaces().length > 0) {
throw new IllegalArgumentException("API interfaces must not extend other interfaces.");
}
}
如果service不是接口类型或者service实现了某个接口都会在编译时报错!
2、是否需要提前使方法合理化
if (validateEagerly) {
eagerlyValidateMethods(service);
}
这个是上面解析创建时validateEagerly参数初始化的遗留问题,它的作用也就在这一行代码里(决定是否需要提前使方法合理化,具体为什么要这样设计,我也不太清楚),这个eagerlyValidateMethods()方法里面最后调用了loadMethodHandler(method),因为动态代理的时候也会调用,所以这个合理化接口的方法的作用留到后面解释。
3、生成动态代理对象
动态代理这个就不说了吧,如果不了解就可以google或百度一下,return就是一个动态代理对象。动态代理对象调用它的方法返回的是return method.invoke(this, args);当然里面做了判断:
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
如果传入的final Class<T> service 是一个Object.class 的话才按照正常的返回,这个呢对动态代理有过了解的应该可能会知道,正常返回意味着什么了(这个返回就是调用代理对象的方法的返回,可以是null但是一定会执行方法)。
这里只对不正常返回做解释了。因为create方法一开始就指定service必须是interface:
MyApi api = retrofit.create(MyApi.class);
Response<User> user = api.getUser().execute();
这里的MyApi是一个接口interface类型的(这里就不是Object了)所以method.getDeclaringClass() == Object.class 会返回false。再往下走:
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
这个platform.isDefaultMethod(method)方法(和java8.0有关吧),不过源码写死的返回false:
boolean isDefaultMethod(Method method) {
return false;
}
那就不管了再往下走,就是关键代码返回了:
return loadMethodHandler(method).invoke(args);
- loadMethodHandler(method)使方法合理化(传入的是一个interface的class对象,interface的方法都没有被实现,当然“不合法”):确定代理对象里包含的的方法名称(当然和接口的方法名称是一样的)+通过解析注释来确定代理对象的这个方法具体要做些什么(当然是网络请求返回结果)。
- invoke(args):传入代理对象调用代理对象的方法时需要的参数(进行网络请求的参数)如果代理对象调用了它的方法(进行网络请求),就会返回一个OkHttpCall<>对象(用来进行网络请求:execute());
到这里,这个代理对象的创建也完成了,接下来就是调用的对象的方法,完成网络的请求任务并返回结果了,就像下面使用的代码那样:
MyApi api = retrofit.create(MyApi.class);
Response<User> user = api.getUser().execute();
三、动态代理对象方法调用的原理解析
动态代理对象创建完成时,就可以直接调用它的方法完成相应的任务,那么Retrofit的内部是怎么实现让这个代理对象具备这样的能力的呢?
接到Retrofit的create方法里的最后一行代码看:
return loadMethodHandler(method).invoke(args);
首先我们看一下loadMethodHandler(method)做了什么事情:
MethodHandler loadMethodHandler(Method method) {
MethodHandler handler;
synchronized (methodHandlerCache) {
...
if (handler == null) {
handler = MethodHandler.create(this, method);
...
}
}
return handler;
}
它就是创建并返回了一个MethodHandler 对象,先看一看MethodHandler 对我们传入的方法做了些什么,才使得传入的方法“合法化”了呢。
首先创建MethodHandler的代码(调用MethodHandler的静态方法create):
handler = MethodHandler.create(this, method);
这里传入了retrofit本身的实例化对象,和service的方法method对象;下面是create方法的具体内容:
static MethodHandler create(Retrofit retrofit, Method method) {
CallAdapter<?> callAdapter = createCallAdapter(method, retrofit);
Type responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw Utils.methodError(method, "'"
+ Types.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
Converter<ResponseBody, ?> responseConverter =
createResponseConverter(method, retrofit, responseType);
RequestFactory requestFactory = RequestFactoryParser.parse(method, responseType, retrofit);
return new MethodHandler(retrofit.callFactory(), requestFactory, callAdapter,
responseConverter);
}
先看看new MethodHandler()里需要4个参数:
MethodHandler(okhttp3.Call.Factory callFactory,
RequestFactory requestFactory,
CallAdapter<?> callAdapter,
Converter<ResponseBody, ?> responseConverter)
这4个参数基本上是在MethodHandler 的静态方法里creat()进行初始化的,先看看 CallAdapter<?>初始化吧!
1、用Retrofit的最后一个CallAdapterFactory创建CallAdapter
从这里开始呢,方法“合法化”的操作就会正式开始了,首先创建callAdapter ,先别管他是用来干嘛的,先看看具体实现。通过createCallAdapter(method, retrofit)来创建具体实现是:
private static CallAdapter<?> createCallAdapter(Method method, Retrofit retrofit) {
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw Utils.methodError(method,
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw Utils.methodError(method, "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 Utils.methodError(e, method, "Unable to create call adapter for %s", returnType);
}
}
- 检查method的返回值(method.getGenericReturnType())。为泛型和通配符或者为空,编译都不会通过
- 以列表的形式获取method的注解annotations(这个最终好像没有用到),最终才调用retrofit的callAdapter()方法,该方法又会继续调用retrofit的nextCallAdapter()方法: return nextCallAdapter(null, returnType, annotations);,由于该方法过长就不贴全部了,关键代码如下:
public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,Annotation[] annotations) {
...
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;
}
}
...
}
skipPast传入的是一个空对象不用管
adapterFactories还记得吧!就是构建retrofit的时候build()方法里初始化的,而且还自动添加了一个默认的CallAdapterFactory:
adapterFactories.add(Platform.get().defaultCallAdapterFactory(callbackExecutor));
那么从nextCallAdapter()方法可以看出,返回的就是adapterFactories容器里的最后一个CallAdapterFactory对象调用get方法所创建的CallAdapter对象了。
看一下实现了CallAdapter.Factory这个接口的DefaultCallAdapterFactory是怎么写的创建方法的:
@Override
public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
...
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public <R> Call<R> adapt(Call<R> call) {
return call;
}
};
}
直接返回了匿名实现的CallAdapter<Call<?>>,其实这里就是一个适配器模式(其他调用者必须将用于网络请求的对象转换成一个Call<R>对象)
@Override public <R> Call<R> adapt(Call<R> call)这个方法的实现就是返回的一个Call实例,用于做网络请求的。
2、生成用来作网络请求的实例:OkhttpOkHttpCall<>
好了到了这里我们先不去看new MethodHandler()的其他几个参数具体是怎样初始化的,因为还记得retorfit的create()方法吗?最后一句:
return loadMethodHandler(method)
.invoke(args);
现在我们loadMethodHandler(method)就告一段落了,其他的几个参数到后面在具体解析(这个方法就是用来创建MethodHandler的实例的)。接下来看一下MethodHandler的invoke(args)做了什么:
Object invoke(Object... args) {
return callAdapter.adapt(
new OkHttpCall<>(callFactory, requestFactory, args, responseConverter));
}
invoke方法将已经实例化的callAdapter的adapt方法传入的 new OkHttpCall<>作为返回。
小结
现在就可以基本对Retrofit的网络请求实现原理写一个结论出来:
- 通过build模式创建一个Retrofit
- 调用创建出的retorfit的create方法(动态代理模式)创建代理对象
- (被代理对象是一个interfafe)所以要通过MethodHandler,使方法“合理化”(主要是解析注解和构建request,下面的分析会讲到)。
- 如果在构建retrofit时,没有对addCallAdapterFactory做配置就会采用默认的DefaultCallAdapterFactory生成Call适配器,那么代理对象调用方法的返回值,也就是invoke方法的返回,是通过callAdapter.adapt()的返回,其实最终就是一个继承了Call<>的OkHttpCall<>了。
例如
MyApi api = retrofit.create(MyApi.class);
* Response<User> user = api.getUser().execute();
这里的MyApi api就是被这个生成的代理对象赋值,代理对象和被代理对象拥有同名方法getUser(),这里的这个getUser()方法返回值就是MethodHandler.invok()的返回值OkHttpCall<>了。execute()就是OkHttpCall<>里面的网络请求的方法。
四、OkHttpCall<>对象
execute()的具体实现这里先不去分析,有几个网络请求的问题先捋一捋:
- 网络请求方法所需要的参数怎么传进去的(其实就是args),是怎么处理这些参数的?
- 一个网络请求的链接怎么拼接的?
- 怎么判断用GET还是用POST?
- ...
其实这些都是通过对Annotation(注解)的解析实现的,既然最后都是用OkHttpCall<>的具体对象来做的网络请求,那这一部分就主要探寻OkHttpCall<>前世今生吧!
1、OkHttpCall<>的创建
OkHttpCall<>第一次被创建的地方就是在MethodHandler里初始化的callAdapter的adapt方法里。
new MethodHandler()所需要的4个参数除了callAdapter,其他三个参数都是用来创建OkHttpCall<>对象的,当然创建OkHttpCall<>对象也需要4个参数:
OkHttpCall(okhttp3.Call.Factory callFactory,
RequestFactory requestFactory,
Object[] args,
Converter<ResponseBody, T> responseConverter)
args,就是通过动态代理得到的method方法里所需要的参数的一个列表,在调用MethodHandler的invoke方法时传入(参考源码或者上一章Retrofit的creat()和MethodHandler部分的代码)。
而其他的三个参数都要通过MethodHandler的静态方法 create()里传入的retorfit对象获得。以下是三个参数的初始化方式:
- callFactory:
retrofit.callFactory();
- responseConverter :
Converter<ResponseBody, ?> responseConverter =
createResponseConverter(method, retrofit, responseType);
- requestFactory:
RequestFactory requestFactory = RequestFactoryParser.parse(method, responseType, retrofit);
因为OkHttpCall<>没有对method的注解做任何操作,所以method的注解的解析操作就与requestFactory或者responseConverter有关了。
callFactory:
retrofit.callFactory()返回的就是一个OkHttpClient对象,这个在构建Retrofit的章节说过。
responseConverter :
responseConverter的初始化与callAdapter的初始化类似最终调用了retrofit的nextRequestBodyConverter关键代码:
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter<ResponseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
上面的循环也是为了取出容器里的最后一个实例。如果在构建retrofit没有设置,就会拿到默认的工厂实例。并用这个工厂实例创建一个Converter<ResponseBody, ?>的实例
当然看到这个converterFactories是不是也很熟悉呢?没错这家伙在Retrofit.Build里被初始化的同时也加入了一个默认的Converter.Factory的实例(在Retrofit.Build的构造方法里):
public Builder() {
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
}
好,那么我们看看这里是怎么样创建Converter<ResponseBody, ?>实例的方法:
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (type == ResponseBody.class) {
if (Utils.isAnnotationPresent(annotations, Streaming.class)) {
return StreamingResponseBodyConverter.INSTANCE;
}
return BufferingResponseBodyConverter.INSTANCE;
}
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}
看看,这里就在对method的注解进行判断了(现在你就可以猜想一下这个Converter<ResponseBody, ?>的具体功能),通过判断的结果返回的可能有三种实例,都是单例的看一下这三种实例,内部都实现那些方法:
static final class RequestBodyConverter implements Converter<RequestBody, RequestBody> {
static final RequestBodyConverter INSTANCE = new RequestBodyConverter();
@Override public RequestBody convert(RequestBody value) throws IOException {
return value;
}
}
static final class StreamingResponseBodyConverter
implements Converter<ResponseBody, ResponseBody> {
static final StreamingResponseBodyConverter INSTANCE = new StreamingResponseBodyConverter();
@Override public ResponseBody convert(ResponseBody value) throws IOException {
return value;
}
}
static final class BufferingResponseBodyConverter
implements Converter<ResponseBody, ResponseBody> {
static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();
@Override public ResponseBody convert(ResponseBody value) throws IOException {
try {
// Buffer the entire body to avoid future I/O.
return Utils.buffer(value);
} finally {
value.close();
}
}
}
哦哦 看到这里是不是有点眼熟啊
@Override public ResponseBody convert(ResponseBody value)这个方法又是对传入的参数做了一个转换!看一下接口Converter的定义:
public interface Converter<F, T> {
T convert(F value) throws IOException;
...
}
将F转为T,不过三个具体实现都是Converter<ResponseBody, ResponseBody>,所以这里有些看不懂呢,不过没关系,这个参数先到这里为止吧!不影响继续探索。
requestFactory:
在MethodHandler里requestFactory是像这样创建的
RequestFactory requestFactory = RequestFactoryParser.parse(method, responseType, retrofit);
静态方法RequestFactoryParser.parse(),那么就去看看这个类里具体是怎么创建requestFactory的吧:
static RequestFactory parse(Method method, Type responseType, Retrofit retrofit) {
RequestFactoryParser parser = new RequestFactoryParser(method);
Annotation[] methodAnnotations = method.getAnnotations();
parser.parseMethodAnnotations(responseType, methodAnnotations);
parser.parseParameters(retrofit, methodAnnotations);
return parser.toRequestFactory(retrofit.baseUrl());
}
首先是初始化自己,并在自己的构造方法里把传入的method全局化。在看到Annotation[]注解列表了没有?说明RequestFactoryParser这个类先对methodAnnotations进行解析,然后将解析的结果用在在toRequestFactory()方法对RequestFactory里做了对初始化:
private RequestFactory toRequestFactory(BaseUrl baseUrl) {
return new RequestFactory(httpMethod, baseUrl, relativeUrl, headers, contentType, hasBody,
isFormEncoded, isMultipart, requestActions);
}
那么这个类其实最关键的作用就是解析method的注解了。有两个重要的方法也是它在静态方法里调用的那两方法:
//对method方法注解类型做判断调用解析方法,将注解名称赋值相关全局变量,
//如果注解的value不为空也要赋值给付给全局变量,这些全局变量就是用来创建RequestFactory的。
parser.parseMethodAnnotations(responseType, methodAnnotations);
//对method参数的注解做解析,将注解名称赋值相关全局变量,这些全局变量也是用来创建RequestFactory的。
parser.parseParameters(retrofit, methodAnnotations);
这里具体是怎么解析的可以看一下源码,代码太长了就不贴了,里面涉及到了很多注解类型的判断,想了解具体的实现,看一下这个RequestFactoryParser类里面的具体实现,代码总长度也很正常500多行。就看这两个重要方法就可以了。
好了拿到所有的注解类型,以及注解的value(一般是relativeUrl,和baseUrl一起用来拼接请求链接的),就可以创建RequestFactory了。
RequestFactory
RequestFactory,从名字就可以看出,是用来创建Request的,它在RequestFactoryParser里拿到的所有参数就是用来创建Request的,这个工厂类里只有一个create方法:
核心实现就是:
RequestBuilder requestBuilder =
new RequestBuilder(method, baseUrl.url(), relativeUrl, headers, contentType, hasBody,
isFormEncoded, isMultipart);
...
return requestBuilder.build();
里面也是build模式创建的request,中间省略的代码,其作用我也不确定,所以暂时不写它的作用了,以后确定了再补上。
当然RequestBuilder里面为了请求体Request的构建也做了大量大操作,最终创建了Request,详细的内容只有再去撸源码了,这里我也不能说的很清楚了。
那么到这里就找到了创建OkHttpCall<>所用到的所有参数了创建也在这里结束。接下来看看OkHttpCall<>用这些参数能做些什么事情。
五、OkHttpCall<>网络请求的真实面目
还记得第三章最后写到的例子吗:
MyApi api = retrofit.create(MyApi.class);
Response<User> user = api.getUser().execute();
这里的MyApi api就是被这个生成的代理对象赋值,代理对象和被代理对象拥有同名方法getUser(),这里的这个getUser()方法返回值就是MethodHandler.invok()的返回值OkHttpCall<>了。execute()就是OkHttpCall<>里面的网络请求的方法。
retrofit的最后一哆嗦就是调用用我们创建的OkHttpCall<>的execute()完成网络请求。execute()方法内容就比较长涉及到的也跟构建OkHttpCall<>传入的4个参数有关。这些参数在上一章中有详细的讲解,这里就不多说了。还是贴一下execute()的部分代码看看
@Override public Response<T> execute() throws IOException {
okhttp3.Call call;
...
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel();
}
return parseResponse(call.execute());
}
这里创建的okhttp3.Call 是通过createRawCall()方法创建的,先不管后面的代码,直接看看createRawCall()方法是怎么写的:
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
callFactory通过几次的传递,终于开始发挥它的作用了,一开始就知道他是一个OkHttpClient,在这里就是调用它的newCall()用来创建一个Call,这个方法需要一个Request,在上一章尾门已经知道了Request是怎么来的了。那么直接看newCall方法的内部:
return new RealCall(this, request);
返回的是RealCall,它实现了Call的接口,那么OkHttpCall的execute()方法最后返回值的时候就是解析的这个RellCall 的execute()方法的返回值。这知道怎么用OkHttp得是不是很眼熟?看一下OkHttp的使用示例代码:
String url = "https://www.baidu.com/";
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
Call call = okHttpClient.newCall(request);
try {
Response response = call.execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
六、总结
从这段请求示例来看,最后总结Retrofit所做的事情就是:
- create生成一个我们自己写好的接口(这个接口的方法、方法里的参数都要有Retrofit对应的注解做标记)的动态代理对象。
- 在创建动态代理对象的过程中要对被代理对象(我们写好的接口)里的方法作合法化处理。
- 方法的合理化确切的说是在调用代理对象的方法(与我们写的接口里的方法同名)时开始的,也就是那个创建MethodHandler.create()开始的。
- 最开始是初始化CallAdapter.
- 然后初始化requestFactory,在这里就解析了所有的注解拼接了字段。为创建OkHttp.Requst做准备。
- 在合法化处理第二个步骤就是MethodHandler的invoke()方法,通过CallAdapter的adpt方法创建了OkHttpCall<>。
- 接下来发生的所有事情就是在这个OkHttpCall<>里了。它用到了一直没有用过的CallFactory也就是OkHttpClient创建了RealCall对象,创建这个对象时用到了requestFactory.creat()方法(这里把也是一直没有用到的args,也就是用于网络请求的参数传了过去),返回的Request对象。至此OkHttpClient已经配置全部完成!
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.example.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
MyApi api = retrofit.create(MyApi.class);
Response<User> user = api.getUser().execute();
上面这段代码中getUser(),就是那个代理对象的方法。法返回的就是OkHttpCall<>对象,同时OkHttpCall<>已经将OkHttpClient(请求的方法、参数)配置好了。最后就是调用execute()方法,其实际就是调用了OkHttpClient创建的RealCall对象的execute()方法。然后再用parseResponse()将okhttp3.Response转换成retrofit2.ResPonse作为最后网络请求的结果返回。
那具体的网路请求的实现(RealCall对象的execute()方法)就是OkHttpClient的事情了。具体的实现就要看OkHttp的源码了,这个就留在下次解析吧。
结束!
网友评论