Retrofit 源碼解析
簡(jiǎn)單用法
Retrofit最簡(jiǎn)單的用法就是定義一個(gè)接口,創(chuàng)建Retrofit
對(duì)象,調(diào)用create()
方法得到一個(gè)service
,
然后自己根據(jù)service
中的方法去做同步或者異步的請(qǐng)求,拿到數(shù)據(jù)對(duì)象,十分簡(jiǎn)單快速,簡(jiǎn)單代碼如下:
public interface GitHub {
@GET("/repos/{owner}/{repo}/contributors")
Call<List<Integer>> contributors(@Path("owner") String owner,@Path("repo") String repo);
}
.創(chuàng)建
Retrofit retrofit = new Retrofit.Builder().baseUrl("xxx").build();
.代理
GitHub gitHub = retrofit.create(GitHub.class);
Call<List<Integer>> call = gitHub.contributors("xx", "xx");
.執(zhí)行
call.enqueue(new Callback<List<Integer>>() {
@Override
public void onResponse(Call<List<Integer>> call, Response<List<Integer>> response) {
}
@Override
public void onFailure(Call<List<Integer>> call, Throwable t) {
}
});
流程分析
創(chuàng)建
那這么簡(jiǎn)單的過(guò)程,剛開(kāi)始看的時(shí)候覺(jué)得有點(diǎn)懵逼呀,怎么他就幫你完成了請(qǐng)求,你明明什么都沒(méi)有做,下面我們按照它的流程慢慢來(lái)解析一下整個(gè)過(guò)程。
我們要用Retrofit
,首先自然是要?jiǎng)?chuàng)建它,也就是這行代碼Retrofit retrofit = new Retrofit.Builder().baseUrl("xxx").build();
.
這里創(chuàng)建Retrofit
是通過(guò)它的一個(gè)內(nèi)部類(lèi)Builder
來(lái)創(chuàng)建的,也就是創(chuàng)建者模式,這個(gè)模式很簡(jiǎn)單,不知道的自行百度,谷歌。
好,我們來(lái)看看這個(gè)builder
做了什么,除了初始化有個(gè)Platform.get()
,直接看最后的build()
,其余的方法都是設(shè)置參數(shù),主要就是這個(gè)build()
:
public Builder() {
this(Platform.get());
}
public Retrofit build() {
1.
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
2.
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
3.
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
4.
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
5.
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
首先一初始化,就做了一件事情,是啥Platform.get()
,Platform
是啥?直譯過(guò)來(lái)就是平臺(tái)啊,平臺(tái)是啥?為啥要有平臺(tái)?看下面這個(gè)代碼get()
其實(shí)
就是一個(gè)就是調(diào)用findPlatform()
:
private static final Platform PLATFORM = findPlatform();
static Platform get() {return PLATFORM;}
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
有Android
和Java8
兩種平臺(tái),Android
我們還是能理解的,為啥還有個(gè)Java8
,不要問(wèn)我,我也不知道啊,Retrofit
的作者炒雞暖男,關(guān)心全世界各種碼農(nóng),
我是個(gè)寫(xiě)android代碼的我們就看Android
平臺(tái)就好了
下面我們來(lái)看一下build()
這個(gè)方法:
- 第一步很簡(jiǎn)單,沒(méi)有
baseUrl
拋出異常,最基本的沒(méi)有,事情沒(méi)法干是吧。 - 第二步,如果沒(méi)有給他設(shè)置
callFactory
,那默認(rèn)給他一個(gè)callFactory
,默認(rèn)就是新創(chuàng)建一個(gè)OkHttpClient
,這里可能我們會(huì)有自己做過(guò)一些
處理的OkHttpClient
,比如加了Interceptor
啊之類(lèi)的,設(shè)置進(jìn)來(lái)就好了,就不會(huì)用默認(rèn)的。
有人可能會(huì)問(wèn)啥是callFactory
啊 ?callFactory
嘛,就是call的factory嘛,call是啥,就是請(qǐng)求,factory是啥,就是工廠,callFactory
就是創(chuàng)建請(qǐng)求的
工廠,OkHttpClient
就是一個(gè)很牛逼的創(chuàng)建請(qǐng)求的工廠,不在本文討論范圍內(nèi),就不多言了。 - 第三步,設(shè)置
callbackExecutor
,又來(lái)一個(gè),這callbackExecutor
又是啥呢?callback
就是回調(diào)嘛,啥回調(diào),就是網(wǎng)絡(luò)請(qǐng)求返回回來(lái)數(shù)據(jù)的回調(diào),executor
呢,就是執(zhí)行者
,合起來(lái)就是回調(diào)的執(zhí)行者,意思網(wǎng)絡(luò)成功了之后交給他它了。如果你沒(méi)有設(shè)置它就自己整一個(gè)默認(rèn)的回調(diào)嘛,不能沒(méi)有。但是這里它要搞事情了,它返回了一個(gè)啥?
platform.defaultCallbackExecutor();
來(lái),我們看一下android
下它返回的是啥:
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
是啥?MainThreadExecutor()
啊,啥意思就是主線(xiàn)程啊,下面寫(xiě)的明明白白的Looper.getMainLooper()
再把要執(zhí)行的Runnable
post到主線(xiàn)程上執(zhí)行
因?yàn)樗悄J(rèn)的嘛,可能就說(shuō)大多數(shù)人都是得到數(shù)據(jù)更新UI啊啥的,所以就默認(rèn)在主線(xiàn)程上執(zhí)行回調(diào)了。我就不想拿到數(shù)據(jù)在主線(xiàn)程座做咋辦,我拿到數(shù)據(jù)我就想更新數(shù)據(jù)庫(kù),
我想在IO線(xiàn)程上搞事情,那就自己寫(xiě)個(gè)callbackExecutor
,自己在IO線(xiàn)程上做就好了,人家提供了一個(gè)方法callbackExecutor(Executor executor)
給你,你自己設(shè)置進(jìn)去就好了
- 第四步是啥?看代碼說(shuō)話(huà),那就是設(shè)置
callAdapterFactory
啊 。callAdapterFactory
又是什么鬼啊,和上面一樣啊,拆分一下呀。CallAdapter
啥意思,就是請(qǐng)求的
適配器,請(qǐng)求的適配器是什么鬼啊。來(lái)來(lái)來(lái)我告訴你,你看看源碼里面根目錄是不是有一個(gè)包名字叫做'retrofit-adapter'
,這個(gè)包就是實(shí)現(xiàn)了一些列的CallAdapter
意思就是你想將返回的數(shù)據(jù)用什么東西包裝起來(lái),比如你用Rxjava
的話(huà)想返回Observable
,或者高興,想用Java8
的CompletableFuture
,這些都由你呀。
但是這些都實(shí)現(xiàn)了一個(gè)叫CallAdapter
的接口。我們來(lái)簡(jiǎn)單看看這個(gè)接口:
public interface CallAdapter<R, T> {
Type responseType();
T adapt(Call<R> call);
abstract class Factory {
public abstract CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
Retrofit retrofit);
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}
其實(shí)接口里面就是兩個(gè)方法還有一個(gè)靜態(tài)的工廠類(lèi)。responseType()
這個(gè)方法決定請(qǐng)求回來(lái)之后返回的是什么類(lèi)型的數(shù)據(jù)。比如在示例用法中我們的List<Integer>
adapt()
這個(gè)方法是干嘛的呢?就是適配嘛,就是怎樣把返回回來(lái)的數(shù)據(jù)通過(guò)這個(gè)方法包裝成你想要的對(duì)象。
這里看到這個(gè)名字adapter
你想到了啥,其實(shí)就是傳說(shuō)中的適配器模式啊,就是我給你定義一個(gè)接口放這里,我在框架里的邏輯就用這個(gè)接口來(lái)做就好了,至于你想要怎樣的實(shí)現(xiàn),
想用框架供給你的一些實(shí)現(xiàn)比如Rxjava
或者Java8
的CallAdapter
,或者是你自己心情好想用自己的實(shí)現(xiàn)一個(gè)其他的CallAdapter
,你自己決定就好了。這就是傳說(shuō)中的啥??擴(kuò)展性好啊。
繼續(xù)看build()
這個(gè)方法,它調(diào)用的是adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));· 再回來(lái)
Platform看
defaultCallAdapterFactory()返回的是一個(gè)
ExecutorCallAdapterFactory。這個(gè)類(lèi)他么的又來(lái)干嘛,當(dāng)然是搞事情。 進(jìn)去瞅一眼,發(fā)現(xiàn)了什么?它當(dāng)然是繼承
CallAdapter.Factory了,這個(gè)不說(shuō)了,看幾句代碼來(lái),看它的
get()方法,看看這個(gè)工廠是怎么造
CallAdapter`的:
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
返回了一個(gè)簡(jiǎn)單新創(chuàng)建的實(shí)現(xiàn)CallAdapter
的匿名類(lèi)。注意看看這里的adapt()
方法,前面講了就是用它來(lái)實(shí)現(xiàn)到底返回什么包裝對(duì)象的邏輯。這里返回的是一個(gè)
ExecutorCallbackCall
,ExecutorCallbackCall
是這ExecutorCallAdapterFactory
里面的一個(gè)內(nèi)部類(lèi).來(lái)看看它的代碼:
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
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);
}
});
}
});
}
@Override public boolean isExecuted() {
return delegate.isExecuted();
}
@Override public Response<T> execute() throws IOException {
return delegate.execute();
}
@Override public void cancel() {
delegate.cancel();
}
@Override public boolean isCanceled() {
return delegate.isCanceled();
}
@SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
@Override public Call<T> clone() {
return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
}
@Override public Request request() {
return delegate.request();
}
}
它實(shí)現(xiàn)了Call
這個(gè)接口,Call
我們前面說(shuō)了,是啥,就是一個(gè)請(qǐng)求嘛,然而我們看這里并沒(méi)有實(shí)際做請(qǐng)求而是用了一個(gè)靜態(tài)代理,
通過(guò)代理類(lèi)的實(shí)現(xiàn)來(lái)實(shí)現(xiàn)call請(qǐng)求,而在這里面做了一些其他的邏輯比如cancel
的邏輯,而實(shí)際上做請(qǐng)求的還是交個(gè)了delegate -> OkHttpCall
.
- 第五步,接著看上面的
build()
的代碼,不要著急,第一段代碼還沒(méi)講完呢。第五步是什么?List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
這一步就是關(guān)于Converter
,顧名思義,它就是一個(gè)轉(zhuǎn)換器,什么轉(zhuǎn)換器,數(shù)據(jù)的轉(zhuǎn)換器,我們從后端獲取到的數(shù)據(jù),一般都是一些序列化的數(shù)據(jù),例如json
,xml
,protobuf
之類(lèi)的
而我們前端用到的需要的是一個(gè)對(duì)象,我們就需要吧這些序列化的數(shù)據(jù)轉(zhuǎn)換成我們想要的能直接用的用起來(lái)爽的對(duì)象,這時(shí)候就需要現(xiàn)在登場(chǎng)的這個(gè)東西?,F(xiàn)在json
用的
比較多,我們平時(shí)都會(huì)用什么gson
,jackson
或者其他的三方庫(kù)來(lái)轉(zhuǎn)化它,你覺(jué)得哪個(gè)用起來(lái)高興就可以用什么寫(xiě)一個(gè)Converter
,然后用Builder
中的addConverterFactory
就可以用你想要的了,而且你都不用寫(xiě),因?yàn)楣俜教峁┝撕枚喾NConverter
的,在根目錄下的'retrofit-converters'
這個(gè)包下面,你只需要用就好了,那我們這里如果沒(méi)有設(shè)置過(guò)converterFactories
咋辦?咋辦?沒(méi)設(shè)置,后面找不到會(huì)報(bào)錯(cuò)的。
這里的Response
是Retrofit
對(duì)OkHttp
的ResponseBody
封裝了一些邏輯的類(lèi),源碼就不貼了,自己點(diǎn)進(jìn)去看看。
這里我們順便看看Converter
這個(gè)接口:
public interface Converter<F, T> {
T convert(F value) throws IOException;
abstract class Factory {
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return null;
}
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return null;
}
public Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return null;
}
}
}
接口就一個(gè)方法,就是轉(zhuǎn)換,然后里面還有一個(gè)靜態(tài)的工廠類(lèi)我們看到里面有3個(gè)方法,其實(shí)很好理解。我們需要把返回來(lái)的ResponseBody
里的數(shù)據(jù)轉(zhuǎn)換
成我們想要的東西,我們也會(huì)想要把我們RequestBody
程序里的東西轉(zhuǎn)換成后端想要的東西.就是這個(gè)邏輯拉,這個(gè)工廠類(lèi)就是給我們提供各種轉(zhuǎn)換器,我們
只需要根據(jù)我們自己的需求來(lái)實(shí)現(xiàn)或者使用對(duì)應(yīng)的就好了。這又是啥,還是和上面一樣啊,給你定義一個(gè)接口,接口是什么,就是標(biāo)準(zhǔn),給你一個(gè)標(biāo)準(zhǔn)
你實(shí)現(xiàn)這個(gè)標(biāo)準(zhǔn)就行,我用我這套標(biāo)準(zhǔn)來(lái)實(shí)現(xiàn)我內(nèi)部的邏輯,至于你怎么實(shí)現(xiàn),想用啥方法實(shí)現(xiàn),玩成什么花樣都可以,我不管,只要你遵循了標(biāo)準(zhǔn),就可以。這樣
擴(kuò)展性就好呀。這就是人家大神牛逼之處啊,代碼寫(xiě)到高處就是寫(xiě)標(biāo)準(zhǔn)啊。
講到這里,我們示例用法中的第一句Retrofit retrofit = new Retrofit.Builder().baseUrl("xxx").build();
總算講完了。中間這么多邏輯,這么
多心血,你看,你一句話(huà)就搞定了,是不是該學(xué)習(xí)學(xué)習(xí)。
代理
build好了之后,就是需要的材料都搞齊了,要工廠有工廠要材料有材料,下面我們來(lái)講講這第二句,第二句,那厲害了。其實(shí)他就是啥,利用你定義的一個(gè)充滿(mǎn)各種注解的接口interface GitHub()
來(lái)簡(jiǎn)單粗暴的做了一個(gè)動(dòng)作,
那就是create()
。這個(gè)動(dòng)作看似簡(jiǎn)單,實(shí)則過(guò)于粗暴啊,進(jìn)去看看代碼
public <T> T create(final Class<T> service) {
1.
Utils.validateServiceInterface(service);
2.
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 {
3.
// 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);
}
4.
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
5.
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
6.
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
這里你首先要了解的知識(shí)是泛型,反射,動(dòng)態(tài)代理。如果不懂,請(qǐng)自行g(shù)oogle.好吧,我說(shuō)下動(dòng)態(tài)代理,動(dòng)態(tài)代理就是動(dòng)態(tài)的代理,就是只要你實(shí)現(xiàn)了一個(gè)借口,Proxy
就可以根據(jù)這個(gè)接口來(lái)對(duì)你
實(shí)現(xiàn)代理,也就是說(shuō)Proxy
只能代理實(shí)現(xiàn)了接口的類(lèi)。這也就是為什么我們要寫(xiě)一個(gè)Interface
來(lái)作為Service
,然后在里面寫(xiě)一些注解之類(lèi)的。如果接觸過(guò)JAVAEE
的話(huà),
Spring
里的AOP動(dòng)態(tài)代理是采用cglib
來(lái)修改字節(jié)碼實(shí)現(xiàn)的動(dòng)態(tài)代理,而且不需要實(shí)現(xiàn)接口,感興趣的朋友可以看一下?;氐竭@里,就是通過(guò)Proxy
這個(gè)類(lèi)利用反射,對(duì)你寫(xiě)的接口進(jìn)行解析
獲取到你申明的方法,然后對(duì)你的方法實(shí)現(xiàn)框架想要實(shí)現(xiàn)的邏輯,來(lái)完成所謂的代理。
我們來(lái)看代碼。
- 第一步,就是檢驗(yàn)?zāi)愣x的
service
接口是不是正確。簡(jiǎn)單看下代碼,首先如果不是接口會(huì)拋出異常,還有為了避免出現(xiàn)bug,和保證API都是統(tǒng)一的標(biāo)準(zhǔn),不允許定義的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.");
}
}
- 第二步,如果你在前面
creat()
的時(shí)候,設(shè)置過(guò)validateEagerly
為true
的話(huà),它會(huì)在這一步將所有的你Service
中聲明的Method
在這里都初始化了,并且緩存起來(lái)
private void eagerlyValidateMethods(Class<?> service) {
Platform platform = Platform.get();
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method)) {
loadServiceMethod(method);
}
}
}
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
這里在解析你用annotations
標(biāo)注的Method
時(shí)也一樣用到了Builder
這種模式,通過(guò)ServiceMethod
這個(gè)類(lèi)來(lái)解析你的標(biāo)注,將標(biāo)準(zhǔn)轉(zhuǎn)化為實(shí)際的邏輯。
這里面的代碼比較多,我就不再貼了,其實(shí)里面的邏輯比較單一,但是比較復(fù)雜。主要就是根據(jù)不同的標(biāo)注,來(lái)生成對(duì)應(yīng)的對(duì)象,你用著有多簡(jiǎn)單就有框架來(lái)給你承受多復(fù)雜。只看一下他的Constructor
最后會(huì)得到著一些東西。
ServiceMethod(Builder<R, T> builder) {
this.callFactory = builder.retrofit.callFactory();
this.callAdapter = builder.callAdapter;
this.baseUrl = builder.retrofit.baseUrl();
this.responseConverter = builder.responseConverter;
this.httpMethod = builder.httpMethod;
this.relativeUrl = builder.relativeUrl;
this.headers = builder.headers;
this.contentType = builder.contentType;
this.hasBody = builder.hasBody;
this.isFormEncoded = builder.isFormEncoded;
this.isMultipart = builder.isMultipart;
this.parameterHandlers = builder.parameterHandlers
}
- 第三步,這時(shí)候就進(jìn)入到每個(gè)方法的代理實(shí)現(xiàn)里來(lái)了。實(shí)際上這里面是已經(jīng)進(jìn)入了上面例子中的第三句了,因?yàn)槭菫槊恳粋€(gè)其中的方法實(shí)現(xiàn)代理
Call<List<Integer>> call = gitHub.contributors("xx", "xx");
的流程了。
如果是Object
聲明的方法,直接執(zhí)行原方法,然后platform.isDefaultMethod(method)
在Android
平臺(tái)直接返回false
,所以這里直接忽略。 - 第四步,這里如果第二步?jīng)]有build過(guò)這個(gè)方法,或者緩存里沒(méi)有會(huì)
build
這個(gè)方法,緩存里有的話(huà)直接取過(guò)來(lái)。 - 第五步,根據(jù)
serviceMethod
初始化OkHttpCall
,真正執(zhí)行請(qǐng)求是交給這個(gè)類(lèi)來(lái)執(zhí)行的。 - 第六步,根據(jù)
OkHttpCall
最后返回CallAdapter
適配后的你想要的類(lèi)型.到這里就通過(guò)代理得到了一個(gè)所有參數(shù),headers
或者其他都準(zhǔn)備好了的,并且也通過(guò)CallAdapter
實(shí)現(xiàn)了返回?cái)?shù)據(jù)包裝的一個(gè)完整的數(shù)據(jù)類(lèi)型.
講到這里,準(zhǔn)備工作都已經(jīng)做齊了,就等著最后執(zhí)行了。這里的Call
是根據(jù)你設(shè)置的CallAdapter
來(lái)返回的,比如如果你熟悉Rxjava
,那結(jié)合Rxjava
,這里也可以
返回一個(gè)Observable
.當(dāng)然你在定義這個(gè)Service
接口的時(shí)候也應(yīng)該聲明為這個(gè)返回類(lèi)型。就算是Call
,也不是返回OkHttpCall
,前面講到了ExecutorCallbackCall
來(lái)靜態(tài)代理了
OkHttpCall
,實(shí)際上這里返回的是ExecutorCallbackCall
.
執(zhí)行
如果是ExecutorCallbackCall
的話(huà),提供了同步的excute
和異步的enqueue
來(lái)執(zhí)行這個(gè)請(qǐng)求,并且提供一個(gè)Callback
回調(diào)的接口來(lái)處理調(diào)用成功
或者失敗。調(diào)用之后是如何拿到數(shù)據(jù)之后,被Converter
轉(zhuǎn)化,被CallAdapter
包裝然后返回給我們的呢?
來(lái)我們慢慢分析。前面我們提到了,其實(shí)所有的請(qǐng)求執(zhí)行,實(shí)際上都是OkHttpCall
這個(gè)類(lèi)在操作。OkHttpCall
實(shí)現(xiàn)了Call
接口,就是一些請(qǐng)求的常用邏輯,同步異步cancel等等,
不管是同步還是異步,最后都是拿到返回的Response
轉(zhuǎn)換成我們想要的數(shù)據(jù)。我們挑一個(gè)OkHttpCall
中同步的方法看看:
@Override
public Response<T> execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
... 中間邏輯很簡(jiǎn)單就省略了
return parseResponse(call.execute());
}
}
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
rawResponse = rawResponse.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
if (code < 200 || code >= 300) {
try {
// Buffer the entire body to avoid future I/O.
ResponseBody bufferedBody = Utils.buffer(rawBody);
return Response.error(bufferedBody, rawResponse);
} finally {
rawBody.close();
}
}
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
T body = serviceMethod.toResponse(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
// If the underlying source threw an exception, propagate that rather than indicating it was
// a runtime exception.
catchingBody.throwIfCaught();
throw e;
}
}
首先我們就來(lái)看Retrofit
在執(zhí)行后是怎么講response
轉(zhuǎn)換成我們想要的數(shù)據(jù)的。excute()
執(zhí)行后中間有點(diǎn)失敗取消的邏輯,最后就是直接把成功后的response
交給
parseResponse()
這個(gè)方法,這里先轉(zhuǎn)化為一個(gè)沒(méi)有body
數(shù)據(jù)的response
來(lái)做狀態(tài)判斷,如果需要轉(zhuǎn)換數(shù)據(jù),把原來(lái)的ResponseBody
轉(zhuǎn)換為一個(gè)靜態(tài)代理的ExceptionCatchingRequestBody
交給serviceMethod.toResponse(catchingBody)
,主要是為了做一些異常處理。順著這個(gè)流程我們進(jìn)ServiceMethod
來(lái)看看toResponse()
這個(gè)方法。
/** Builds a method return value from an HTTP response body. */
public ServiceMethod build() {
...
responseConverter = createResponseConverter();
...
}
R toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}
private Converter<ResponseBody, T> createResponseConverter() {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create converter for %s", responseType);
}
}
很簡(jiǎn)單就是交給了Converter
來(lái)做轉(zhuǎn)換。Converter
看起來(lái)是不是很眼熟。前面我們好像設(shè)置了啊。最后又回到了Retrofit
這個(gè)類(lèi),來(lái)看看
responseBodyConverter()
這個(gè)方法:
public <T> Converter<T, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations) {
return nextRequestBodyConverter(null, type, parameterAnnotations, methodAnnotations);
}
public <T> Converter<T, RequestBody> nextRequestBodyConverter(Converter.Factory skipPast,
Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations) {
checkNotNull(type, "type == null");
checkNotNull(parameterAnnotations, "parameterAnnotations == null");
checkNotNull(methodAnnotations, "methodAnnotations == null");
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter.Factory factory = converterFactories.get(i);
Converter<?, RequestBody> converter =
factory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<T, RequestBody>) converter;
}
}
...build string
throw new IllegalArgumentException(builder.toString());
}
其實(shí)很簡(jiǎn)單,就是返回factory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, this);
,就是工廠造一個(gè)Converter
這個(gè)工廠造的Converter
怎么造,框架是不管的,總之你按照我給你定義的標(biāo)準(zhǔn)造一個(gè)來(lái)就是了。感興趣就去看看'retrofit-converters'
這個(gè)包里是怎么造的,也很簡(jiǎn)單
然后通過(guò)Converter
的convert()
方法就把你想要的類(lèi)型數(shù)據(jù)返回給你了,這個(gè)convert()
方法也是你在實(shí)現(xiàn)Converter
要自己實(shí)現(xiàn)的,當(dāng)然源碼里提供了一些實(shí)現(xiàn),你自己去看。
整個(gè)流程就是這樣的。希望對(duì)你閱讀源代碼有幫助。