**(2)defaultCallAdapterFactories:**擷取預設的CallAdapter.Factory,用于建立CallAdapter;
**(3)defaultConverterFactories:**擷取預設的資料轉換工廠ConverterFactory,用于建立轉換器Converter;
總結:Platform主要是用于适配不同的平台,用于擷取預設的Executor,請求擴充卡工廠類CallAdapterFactory,資料轉換工廠類ConverterFactory等;
4.2、baseUrl
baseUrl,是我們網絡請求的基礎URL;
我們進源碼裡面看一下,具體做了啥操作;
這裡主要做了兩步操作:
1、首先第一步是通過解析這個baseUrl并傳回一個HttpUrl對象; 2、第二步是将第一步建立的HttpUrl對象指派給Builder;
這裡我們主要看第一步的具體操作,這裡的邏輯是在HttpUrl的 parse(@Nullable HttpUrl base, String input)裡,通過解析URL,判斷該請求的scheme是為http還是https,如果不是這其中一個,那麼就會抛出異常,源碼我們大緻看一下;
然後下面還會解析URL,擷取到主機位址host,端口号port,具體源碼我就不貼了,感興趣的可以跟着源碼看一下;
4.3、Converter.Factory
這個我們上面在接受Retrofit的成員變量的時候有提過,是用于建立Converter的工廠,使用了抽象工廠的設計模式,而Converter是用來将請求傳回的資料,轉化為對應平台的資料,而這裡,我們使用的是Gson平台;
我們先來看一下這個Converter.Factory,看看其背後是怎麼實作的;
從源碼可以看出,Converter.Factory是Converter的内部類,主要有兩個方法,一個是requestBodyConverter,用于将請求的RequestBody轉換為對應的轉換器Converter;
另一個方法是responseBodyConverter,用于将傳回的傳回體ResponseBody轉換為對應的轉換器Converter;
而轉換器Converter裡面隻有一個方法convert,用于将傳回的資料轉換為對應的類型;
我們在建立Retrofit的執行個體時,是通過GsonConverterFactory.create()來建立對應的轉換器工廠的,下面我們來看看這個Gson的轉換器工廠是怎麼實作的;
先來看一下這個create()的方法;
最終是走的這裡,進行了簡單的指派;
GsonConverterFactory這個工廠最重要的還是responseBodyConverter和requestBodyConverter方法,下面我們來具體分析;
- requestBodyConverter:
在requestBodyConverter方法裡面,通過class的Type類型,建立了Gson的TypeAdapter,這個TypeAdapter很熟悉,就是我們使用gson解析會用到的類,最終通過TypeAdapter和gson的參數建立了GsonRequestBodyConverter對象,下面來瞄一眼這個類的代碼;
這個類的源碼很簡單,我們主要convert()這個方法;
這個方法的邏輯就是将傳進來的value值通過TypeAdapter将其轉化為ByteString,然後再傳進RequestBody作為參數來建構RequestBody對象;
這個方法我們先了解到這裡,後面在這個requestBodyConverter調用的地方再來講一下;
- responseBodyConverter:
這個方法和上面那個requestBodyConverter方法有點類似,也是通過class的Type類型,建立了Gson的TypeAdapter,最終通過TypeAdapter和gson的參數建立了GsonResponseBodyConverter,同理,我們也來看一下這個類的實作吧;
源碼很簡單,這裡我們也是關注convert()這個方法;
這裡的邏輯有沒有很熟悉,就是我們經常用的gson解析,通過TypeAdapter讀取JsonReader的資料,傳回對應的資料類型,這裡的參數ResponseBody就是我們上面GsonRequestBodyConverter的convert方法生成的;
到這裡GsonConverterFactory就講的差不多了,後面我們在用到的地方再詳細講一下;
4.5、CallAdapter.Factory
CallAdapter.Factory,從命名可以看出,是用來建立CallAdapter的工廠類,使用了抽象工廠的設計模式,而CallAdapter是用于将Call轉化為我們所需要的請求類型,比如将Call轉化為RxJava的調用類型;
而CallAdapter裡面是通過adapt方法來進行轉換的,adapt是接口的一個方法,交給子類去實作,這個方法的邏輯,我們下面将Retrofit的解析時,再統一講解,這裡是需要了解這是一個轉換的方法即可;
image.png
下面我們來看看建立CallAdapter的工廠裡面都有哪些方法,分别是用來幹嘛的;
image.png
這個Factory的邏輯很少,隻有幾個方法,這裡我們主要關注get方法,通過get方法來擷取CallAdapter的對象,同理,這裡也是交給子類去實作;
而上面我們Retrifit的建立,在CallAdapter.Factory的添加時,使用了RxJava的工廠,也就是RxJava2CallAdapterFactory,用于将Call請求轉換為RxJava對應的請求;
下面我們來看看這個RxJava2CallAdapterFactory的實作邏輯吧;
RxJava2CallAdapterFactory的建立,也是通過RxJava2CallAdapterFactory.create()的方法,那麼我們來看下這個create方法做了啥?
隻是簡單的new了一個RxJava2CallAdapterFactory,而構造方法裡也沒有其他的邏輯了,隻是對Scheduler進行指派,而這裡建立時,傳的是null;
上面我們看完RxJava2CallAdapterFactory的建立後,下面我們來看一下RxJava2CallAdapterFactory是怎麼通過get方法建立一個CallAdapter的;
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
if (rawType == Completable.class) {
// 建立RxJava2CallAdapter
return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false,
false, true);
}
…
// 建立RxJava2CallAdapter
return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
isSingle, isMaybe, false);
}
這個方法職責很明确,就是根據各種參數來建立RxJava的CallAdpter,也就是RxJava2CallAdapter;
這裡我們來重點關注一個RxJava2CallAdapte的adapt方法的邏輯;
public Object adapt(Call call) {
// 第一步:根據是否是異步的參數建立對應的Observable
Observable<Response> responseObservable = isAsync
- ? new CallEnqueueObservable<>(call)
- new CallExecuteObservable<>(call);
Observable<?> observable;
// 第二步:根據各種判斷,再封裝一層Observable傳回
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
…
return observable;
}
這個方法的邏輯并複雜,主要是将Call請求轉化為RxJava的請求,最終傳回一個RxJava的被觀察者:Observable,用于進行RxJava類型的網絡請求,如上面的示例;
這個方法的邏輯主要有兩步,我們先來看一下第一步建立的被觀察者,這裡會先判斷是否是異步,如果是異步的話,那麼就建立CallEnqueueObservable,否則就建立CallExecuteObservable;
這兩個的差別就是,在調用訂閱(subscribe)的時候,會執行CallEnqueueObservable的subscribeActual方法,最終是通過OkHttpCall的enqueue方法來執行異步請求;
而CallExecuteObservable在調用訂閱(subscribe)的時候,也會執行CallEnqueueObservable的subscribeActual方法,在這個方法裡,就直接調用OkHttpCall的execute方法來執行同步請求;
而第二步的封裝,這裡我們主要以BodyObservable來進行講解,這個類會對訂閱的觀察者進行封裝,在onNext方法中将body傳回;這一步可以了解為對傳回的結果進行處理;
這裡是RxJava的用法,我預設你是會的,如果對RxJava還不熟悉的同學,可以後面去看看RxJava的用法;
到此,Retrofit的CallAdapter.Factory的邏輯就先告一段落了,下面我們來看看Retrofit的最終build()方法的邏輯;
4.5、Retrofit.Builder#build
廢話不多說,我們直接撸源碼;
public Retrofit build() {
// 判斷當callFactory(OkHttpClient)為空,就重新建立一個OkHttpClient進行指派;
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
// 判斷Executor為空時,就用Platform的預設Executor進行指派,上面我們講過,這裡面使用的是主線的的Handler;
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// 通過添加的CallAdapter.Factory來建立一個新的CallAdapter.Factory集合;
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
// 添加Platform的預設CallAdapter.Factory,如果我們沒有添加CallAdapter.Factory,那麼就會使用這個Platform的預設CallAdapter.Factory; callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// 建立Converter.Factory的集合
List<Converter.Factory> converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
// 添加預設的Converter.Factory
converterFactories.add(new BuiltInConverters());
// 添加自定的Converter.Factory
converterFactories.addAll(this.converterFactories);
// 添加Platform的預設Converter.Factory
converterFactories.addAll(platform.defaultConverterFactories());
// 最終建立Retrofit執行個體;
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
這個build()方法,主要是做各種參數的指派,最終通過參數來建立Retrofit的執行個體,那麼到這裡Retrofit的建立就差不多将完了,下面我們将會學習到Retrofit的核心;
為什麼我們可以通過接口定義一個類型,就可以執行請求了,對于這些方法的解析,以及參數的指派的操作是在哪裡呢?
這麼就涉及到Retrofit使用的一個很重要的設計模式了,也就是動态代理設計模式;
5、Retrofit的核心,動态代理
5.1、什麼是代理?
舉個例子,假如我要去超市買水果,可是我好懶,周末就想呆在家裡不想出門,但是心裡又很想吃水果,那怎麼辦呢?
隻能打開外賣App,在上面買完之後,由外賣小哥送過來,這時候,我就通過中介,外賣App來買到水果,而這個過程叫做代理;
不直接操作,而是委托第三方來進行操作,進而達到目的;
而Java的代理分為靜态代理和動态代理;
5.2、什麼是靜态代理?
如果代理類在程式運作之前就已經存在了,那麼這種代理方式就被稱為靜态代理;
還是以上面的例子,我要買水果,來定義一個買水果的接口Operator;
public interface Operator {
// 買水果
void buyFruit();
}
而我們的代理類外賣App需要實作這個接口,同時,将需要委托的對象傳進來,在buyFruit的過程中,做了一些出來,比如去超市取貨,取完貨之後,再送貨;
public class AppAgent implements Operator {
private Operator operator;
public AppAgent(Operator operator) {
this.operator = operator;
}
@Override
public void buyFruit() {
// 1、在App上,提供商品給使用者下單
// 2、根據訂單去超市采購水果
operator.buyFruit();
// 3、送貨給客戶
}
}
委托的對象,超市:
public class Market implements Operator {
@Override
public void buyFruit() {
// 到超市買水果
}
}
那麼最終的實作效果就是,我們通過外賣App的一頓操作,從超市買到了水果,如下:
public class Main {
public static void main(String[] args) {
// 委托對象,超市;
Market market = new Market();
// 代理對象,外賣App;
AppAgent appAgent = new AppAgent(market);
// 通過外賣App的代理,從超市買到了水果;
appAgent.buyFruit();
}
}
以上就是我們靜态代理的過程,這個例子隻是舉了買水果這個過程,但是如果我還想要買菜,買生活用品等一系列東西呢?
我就得在接口Operator裡面再多新增好幾個方法,同樣的代理類也要跟着去重寫一堆的方法,但是這些方法做的操作其實都是一樣的,都是買這個動作,但是我們不得已,新增一種類型,我們就得在代理類裡面再重寫并調用;
那麼這個過程其實是可以抽出來的,這種方式就叫做動态代理;
5.3、動态代理
動态代理,和靜态代理不同的是,動态代理的方法是運作後才建立的,而靜态代理是運作前就存在的了;
說白了,和靜态代理不同的是,動态代理的方法都是在運作後,自動生成的,是以叫動态代理;
下面我們來看看動态代理是咋用的;
在使用動态代理的時候,被代理類需要實作InvocationHandler這個接口,,這個invoke方法是在動态生成的代理類中調用的,對應着我們上面在靜态代理operator.buyFruit()這個方法的調用,下面來看一下這個方法對應的參數;
public interface InvocationHandler {
// Object proxy:接口的具體實作類;
// Method method:解析之後自動生成的方法;
// Object[] args:方法對于的參數;
Object invoke(Object proxy, Method method, Object[] args);
}
而最終運作時生成的代理類,一般名稱會是Proxy1這種,通過Proxy.newProxyInstance()方法來生成的,這個下面會講到,先來看一下下面的僞代碼;
public final class $Proxy0 extends Proxy implements Operator {
public final boolean buyFruit() {
// h是InvocationHandlel,調用了invoke方法;
super.h.invoke(this, m1, (Object[])null);
}
}
}
在生成的代理類中,會實作我們的接口,并重寫方法,在方法裡面通過InvocationHandler回調參數到invoke方法裡,最終通過反射調用被代理對象的方法;
而我們通過實作這個InvocationHandler接口,在invoke方法裡面,通過method.invoke(object, args)可以來調用被代理的方法,然後我們可以在這個method.invoke(object, args)之前或者之後做一些處理,這樣是以的方法都可以一并進行處理,而不是每次新增一個方法,就得重寫一遍邏輯;
下面來看一下具體實作:
public class CustomProxy implements InvocationHandler {
private Object object;
public CustomProxy(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 1、在App上,提供商品給使用者下單
// doSomeThing();
// 2、根據訂單去超市采購東西(在這個方法之前或者之後都可以統一處理操作)
Object invoke = method.invoke(object, args);
// 3、送貨給客戶
// doSomeThing();
return invoke;
}
}
下面來看一下,最終的調用;
public class Main {
public static void main(String[] args) {
// 建立被代理類
CustomProxy customProxy = new CustomProxy(new Market());
//
《Android學習筆記總結+最新移動架構視訊+大廠安卓面試真題+項目實戰源碼講義》
開源分享完整内容戳這裡
動态生成代理類
Operator proxyInstance = (Operator) Proxy.newProxyInstance(Operator.class.getClassLoader(), new Class[]{Operator.class}, customProxy);
// 調用對應的方法
proxyInstance.buyFruit();
}
}
這裡通過Proxy.newProxyInstance()方法,動态生成代理類$Proxy0這種,這裡涉及到的反射的知識,就不再贅述了;
然後動态代理類調用方法,最終會走到CustomProxy的invoke()方法,然後我們在這個方法裡面通過method.invoke(object, args)來進行最終的代理調用,而在這個最終的代理調用的前後,我們可以實作自定義的邏輯;
這個實作了InvocationHandler接口的CustomProxy,更像是一個攔截類,在代理方法的調用過程中進行攔截,然後再實作我們的自定義邏輯;
至此,動态代理你了解了嗎?沒有了解也沒關系,多看幾遍,多練幾遍就可以了;
6、Retrofit的動态代理
6.1、Retrofit為什麼要使用動态代理?
首先,讓我們來想一個問題,Retrofit為什麼要使用動态代理?
使用動态代理的好處就是在調用方法之前,我們可以統一做一些操作,而不必新增一個方法就去寫一遍邏輯;
而Retrofit巧妙的使用了動态代理在調用接口的方法之前,統一的去解析處理Header和URL等操作;
這樣就不用每次在新增一個請求的方法,就去寫一遍這個解析的邏輯;
那麼接下來我們來看看Retrofit的怎麼解析這些接口的;
6.2、Retrofit是怎麼使用動态代理的?
下面我們來看一下Retrofit的create的方法,動态代理的邏輯是在這裡實作的;
public T create(final Class service) {
…
// 驗證接口的參數以及配置是否正确
if (validateEagerly) {
eagerlyValidateMethods(service);
}
// 動态代理
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 {
// 判斷是否是Object,如果是的話,就直接調用方法傳回
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
// 判斷是否是Java8平台的預設方法類型,如果是的話,就調用Java8平台的invokeDefaultMethod方法
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
// 解析方法;
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
這裡我們将這個方法分為兩步;
第一步: eagerlyValidateMethods方法,這個方法的邏輯是用于加載接口的配置,用于判斷接口對應的header,body以及方法的參數等配置是否正确,如果不正确那麼就會抛出異常;
第二步: loadServiceMethod方法,這個方法的邏輯主要是用于解析我們在接口配置的注解以及參數,比如header,body,url等等;
這裡我們重點關注第二步的loadServiceMethod方法方法;
我們來看一下其源碼的具體實作;
ServiceMethod<?> loadServiceMethod(Method method) {
// 先從緩存map集合裡面擷取ServiceMethod;
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
// 如果從緩存map裡面擷取不到ServiceMethod,那麼再通過解析注解,擷取到ServiceMethod對象;
result = ServiceMethod.parseAnnotations(this, method);
// 将解析後的ServiceMethod對象存入到map集合中;
serviceMethodCache.put(method, result);
}
}
return result;
}
這裡做的操作很簡單,就是擷取ServiceMethod,而在擷取ServiceMethod的過程中,會先從緩存的map中擷取,如果擷取不到了再進行解析,這樣就不必擷取一次ServiceMethod,就去解析一次,比較耗性能;
而這個ServiceMethod的類是個抽象類,隻有兩個方法,一個是靜态的parseAnnotations方法,一個是抽象的invoke方法;
我們先來看一下這個parseAnnotations方法;
static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {
// 通過解析接口方法的注解,擷取RequestFactory
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
…
// 解析注解并擷取ServiceMethod對象
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
這個方法的邏輯也不是很複雜,主要分為兩步;
第一步: 擷取RequestFactory;
第二步: 擷取ServiceMethod;
我們先來看第一步的操作;
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
通過Builder來建立RequestFactory,來看看這個Builder做了啥操作;
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
// 擷取方法所有的注解,包括自己聲明的以及繼承的
this.methodAnnotations = method.getAnnotations();
// 擷取方法參數的所有類型,包含泛型;
this.parameterTypes = method.getGenericParameterTypes();
// 擷取方法參數上的所有注解
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
這個方法的邏輯很簡單,就是做一些指派操作,這裡需要注意的是這幾個反射的方法,下面的build方法會用到;
RequestFactory build() {
for (Annotation annotation : methodAnnotations) {
// 周遊方法的注解,解析方法的參數配置,擷取到請求的url,header等參數
parseMethodAnnotation(annotation);
}
…
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
// 周遊方法的參數,以及參數的類型,解析方法的參數邏輯
parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p]);
}
…
// 根據上面解析的參數配置,建立RequestFactory
return new RequestFactory(this);
}
這個方法的邏輯就比較重要了,我們在接口的方法裡面定義的相關url,header等注解,最終就是在這裡解析并轉化為okhttp請求的Call,那麼我們來看看這裡到底是怎麼解析的;
先來看一下parseMethodAnnotation這個方法, 這個方法的主要邏輯是用于解析方法注解的配置資訊;
下面我們來看看這個類的具體實作;
這個方法的邏輯比較多,我們大緻看一下就可以了,這裡面做的主要職責就是通過注解Annotation,擷取到url,header,isMultipart等參數,并将其指派給建造者Builder的成員變量;
對于這個方法,這裡就不多說了,感興趣的跟着源碼去看一下;
而第二個方法parseParameter,也是周遊上面擷取到的方法的參數類型parameterTypes以及方法參數的注解parameterAnnotationsArray,來解析并擷取相關配置,而這個方法最終是調的parseParameterAnnotation方法的邏輯;
主要是用于解析這裡的邏輯:
下面我們來看看具體實作;
這個parseParameterAnnotation方法的邏輯和上面的parseMethodAnnotation方法有點類似,也是通過判斷對于的類型來進行解析,這裡源碼過長,就不貼出來了;
這裡我們就找其中一個Query的解析來進行分析;
省略前面的代碼
…
else if (annotation instanceof Query) {
…
// 将注解annotation強轉為Query
Query query = (Query) annotation;
// 擷取注解Query對應的值;
String name = query.value();
…
if (Iterable.class.isAssignableFrom(rawParameterType)) {
// 判斷這個參數的類型為Class類型;
…
// 建立ParameterHandler的子類Query
return new ParameterHandler.Query<>(name, converter, encoded).iterable();
}
…
}
…
省略後面的代碼
這裡最終解析擷取的是ParameterHandler.Query類,這個類裡面有個apply的方法,會在接口請求的時候會調用到,目的是通過請求的RequestBuilder将解析出來的參數,添加到RequestBuilder裡去;
這裡我們了解一下就可以了;
這裡還有一個需要注意的點,就是這裡的解析,涉及到Converter這個convert方法的邏輯;
這裡我以Body為例,在Body這個類的apply方法裡,會通過Converter這個convert方法,将body參數轉化為對應類型的資料;
這個apply的方法是在進行網絡請求的時候會調用,具體調用鍊如下,這裡以RxJava為例:
1、RxJavaCallAdapterFactory.ResponseCallAdapter的adapt方法;
2、RxJavaCallAdapterFactory.CallOnSubscribe的call方法;
3、RxJavaCallAdapterFactory.RequestArbiter的request方法;
4、OkHttpCall的execute方法;
5、OkHttpCall的createRawCall方法;
6、RequestFactory的create方法;
7、ParameterHandler的apply方法;
最終在這裡觸發了apply方法的調用,這裡源碼就不貼出來了,感興趣的朋友,可以跟着源碼去看一遍;
我們上面看的RequestFactory的build方法的最後一個,建立RequestFactory,這裡的邏輯就是将我們上面解析出來的參數,給這個RequestFactory進行指派;
那麼到這裡parseAnnotations的第一步就講完了,先來總結一下,這一步主要是解析方法注解和方法參數的注解,進而擷取到對應的參數配置,最終将其指派給RequestFactory對象;
下面我們來看HttpServiceMethod的parseAnnotations方法;
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
// 建立CallAdapter
CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);
…
// 建立Converter
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
// 通過參數建立HttpServiceMethod
okhttp3.Call.Factory callFactory = retrofit.callFactory;
return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}
這個方法的邏輯并不複雜,主要分三步:
第一步: 建立CallAdapter;
第二步: 建立Converter;
第三步: 通過參數建立HttpServiceMethod;
這裡主要關注的是前兩步,建立了CallAdapter和Converter;
我們先來看一下第一步的邏輯;
這裡的調用鍊是這樣的,首先調用了HttpServiceMethod的createCallAdapter方法,然後再調用了Retrofit的callAdapter方法,最後調用了Retrofit的nextCallAdapter方法;
我們來看看nextCallAdapter的邏輯;
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
…
// 通過callAdapterFactories的get方法來建立CallAdapter
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
…
}
這裡的邏輯不複雜,最終通過CallAdapter.Factory來建立CallAdapter,而這個CallAdapter.Factory的邏輯我們上面已經講過了,就是用來建立CallAdapter的工廠;
下面我們來看第二步的調用;
第二步的調用鍊是這樣的,先調用HttpServiceMethod的createResponseConverter方法,然後再調用Retrofit的responseBodyConverter方法,最終調用了Retrofit的nextResponseBodyConverter方法,我們來看看nextResponseBodyConverter這個方法的邏輯;
public Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
…