之前在Retrofit源码初探一文中我们提出了三个问题:
- 什么时候开始将注解中参数拼装成http请求的信息的?
- 如何产生发起http请求对象的?
- 如何将对象转换成我们在接口中指定的返回值的?
其中第一个问题前几篇文章已经做了解答,今天我们探究下第二个问题。
之前也分析过,具体生成这个请求对象的是这句代码:
OkHttpCall
代码很简单,那我们就来探究下这个OkHttpCall能干什么:
finalclassOkHttpCallimplementsCall{
可以看到其实主要实现了一个接口,所以我们看下这个接口都有哪些方法:
publicinterfaceCallextendsCloneable{
Responseexecute()throwsIOException;
voidenqueue(Callbackcallback);
booleanisExecuted();
voidcancel();
booleanisCanceled();
Callclone();
/**TheoriginalHTTPrequest.*/
Requestrequest();
}
看到这几个方法有没有很熟悉,没错,几乎和Okhttp的Call方法一模一样,我们看下okhttp的call接口:
publicinterfaceCallextendsCloneable{
Requestrequest();
Responseexecute()throwsIOException;
voidenqueue(Callbackvar1);
voidcancel();
booleanisExecuted();
booleanisCanceled();
Callclone();
publicinterfaceFactory{
CallnewCall(Requestvar1);
}
}
从这里我们猜测,Retrofit的OkHttpCall其实就是对OkHttp的call的一种包装,下面我们详细探究下每种方法,看是如何分别调用OkHttp的call中的方法的,有没有做什么特殊处理。
之前有提过看源码之前要带着问题去看,那么对于这个OkHttpCall我们想知道什么?之前提到过这是对OkHttp的okhttp3.Call的一个封装,那么每个方法必然会调用到okhttp3.Call对应的方法,所以我们提出两个问题:
- 这个类中okhttp3.Call对象是怎么生成的?
- 调用okhttp3.Call中对应的方法时有没有做什么特殊操作?
这两个问题在每个主要方法中都能得到答案。
request()方法
@OverridepublicsynchronizedRequestrequest(){
okhttp3.Callcall=rawCall;
if(call!=null){
returncall.request();
}
if(creationFailure!=null){
if(creationFailureinstanceofIOException){
thrownewRuntimeException("Unabletocreaterequest.",creationFailure);
}elseif(creationFailureinstanceofRuntimeException){
throw(RuntimeException)creationFailure;
}else{
throw(Error)creationFailure;
}
}
try{
return(rawCall=createRawCall()).request();
}catch(RuntimeException|Errore){
throwIfFatal(e);//DonotassignafatalerrortocreationFailure.
creationFailure=e;
throwe;
}catch(IOExceptione){
creationFailure=e;
thrownewRuntimeException("Unabletocreaterequest.",e);
}
}
可以看到,大致逻辑就是如果okhttp3.Call已经被实例化了直接调用它的request()方法,如果没有的话,会调用createRawCall()方法先实例化,然后再调用request方法。
所以想要解答okhttp3.Call是怎么生成的,就来看看这个createRawCall()方法:
privateokhttp3.CallcreateRawCall()throwsIOException{
okhttp3.Callcall=serviceMethod.toCall(args);
if(call==null){
thrownewNullPointerException("Call.Factoryreturnednull.");
}
returncall;
}
可以看到核心方法还是ServiceMethod中的toCall方法来生成的,这里提供了参数而已,继续跟进去:
okhttp3.CalltoCall(@NullableObject...args)throwsIOException{
RequestBuilderrequestBuilder=newRequestBuilder(httpMethod,baseUrl,relativeUrl,headers,
contentType,hasBody,isFormEncoded,isMultipart);
@SuppressWarnings("unchecked")//Itisanerrortoinvokeamethodwiththewrongargtypes.
ParameterHandler