一.Retrofit中Builder模式完成初始化工作
Retrofit現(xiàn)在已經(jīng)是各種網(wǎng)絡(luò)請(qǐng)求類APP的標(biāo)配了,我們今天主要看下他的內(nèi)部是如何解耦實(shí)現(xiàn)的
首先展示一下基本用,也就是我們?cè)创a分析的入口代碼:
Retrofit retrofit = new Retrofit.Builder().
baseUrl(BASE_URL).
//addCallAdapterFactory(RxJavaCallAdapterFactory.create()). 如果有這句的話就沒有下面的call.enqueue(new Call<List<Bean>>()那段了,直接就用了RxJava那一套了
addConverterFactory(GsonConverterFactory.create()).
build();
Service service = retrofit.create(Service.class);
Call<List<Bean>> call = service.getBeanLists(“username”);
call.enqueue(new Call<List<Bean>>(){
@Override
public void onResponse(Call<List<Bean>> call, Response<List<Bean>> response) {
beanList = response.body();
... //doSomething();
}
@Override
public void onFailure(Call<List<hot>> call, Throwable t) {
Toast.makeText(getContext(), "讀取失敗,請(qǐng)檢查網(wǎng)絡(luò)設(shè)置", Toast.LENGTH_SHORT).show();
}
});
public interface Service {
@GET("{username}")
Call<List<Bean>> getBeanLists(@Path("username") String username);
}
上述我們就創(chuàng)建了一個(gè)異步請(qǐng)求的Retrofit類,我們先從.Build();
開始看起:
public static final class Builder {
private final Platform platform; //選擇平臺(tái):Android,java等
private okhttp3.Call.Factory callFactory; //okhttp的Call工廠類,自定義newCall將Request轉(zhuǎn)為Call
private HttpUrl baseUrl; //okhttp中的類,保存解析過的url。baseUrl就是上面BASE_URL
private final List<Converter.Factory> converterFactories = new ArrayList<>();//類型轉(zhuǎn)換工廠列表
private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>();//CallAdapter工廠列表
private Executor callbackExecutor; //回調(diào)線程池
private boolean validateEagerly;
Builder(Platform platform) {
this.platform = platform;
converterFactories.add(new BuiltInConverters()); //添加默認(rèn)的轉(zhuǎn)換器(如果上面addConverterFactory中不添加的話)
}
public Builder() {
this(Platform.get());
}
......
當(dāng)程序執(zhí)行完Retrofit retrofit = new Retrofit.Builder()
這一句的時(shí)候,也就是執(zhí)行了上述代碼中的
public Builder() {
this(Platform.get());
}
這個(gè)方法,其中Platform.get()
這個(gè)方法,實(shí)際上就是獲取當(dāng)前執(zhí)行的平臺(tái),在Retrofit 2.0版本中,他支持Android,iOS,Java8三個(gè)平臺(tái)。但是在2.2版本的源碼中,刪去了iOS平臺(tái)選擇的那部分源碼,不知道是否還兼容iOS平臺(tái),這個(gè)不在本文討論范圍內(nèi),有興趣的同學(xué)可以自行考證。判斷完平臺(tái)之后,賦值給Platform實(shí)例變量,我們都是Android平臺(tái)。
??上面我們看了.Builder()
方法,這個(gè)方法中實(shí)際上就行選擇了一下平臺(tái)。這個(gè)方法執(zhí)行完之后,開始進(jìn)行addCallAdapterFactory()
,addConverterFactory()
等Build模式中的方法:
/** Add converter factory for serialization and deserialization of objects. */
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
/**
* 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;
}
可以看到,這里我們添加的RxJavaCallAdapterFactory.create()
和GsonConverterFactory.create()
都加到了上面我們提到過的Builder類中的實(shí)例變量List<Converter.Factory> converterFactories
和List<CallAdapter.Factory> adapterFactories
這兩個(gè)List中,一遍后面解析使用。
??Build模式的最后一步.build()
方法:
public Retrofit build() {
if (baseUrl == null) { //baseUrl肯定是要設(shè)置的,不設(shè)置的話會(huì)拋出異常
throw new IllegalStateException("Base URL required.");
}
//如果我們需要對(duì)OkHttp做出一些改進(jìn),比如添加鏈接超時(shí)什么得,就需要重新構(gòu)建OkHttpClient并傳入這里
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) { //如果沒有設(shè)置callFactory,則默認(rèn)用OkHttpClient()
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
//讀取設(shè)置的adapterFactories,也就是addCallAdapterFactory(RxJavaCallAdapterFactory.create())
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// 讀取converterFactories,也就是addConverterFactory(GsonConverterFactory.create())
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly); //最后一步,調(diào)用Retrofit構(gòu)造函數(shù),創(chuàng)建一個(gè)實(shí)例
}
上面的.build()
中方法中,主要做了這么幾件事情:
① 首先指定baseUrl,這個(gè)是必須指定的,否則會(huì)拋出異常
② 獲取callFactory,如果沒有設(shè)置,則默認(rèn)返回new OkHttpClient()
③獲取當(dāng)前的callbackExecutor,即回調(diào)線程池。這個(gè)東西可以自己設(shè),當(dāng)然一般情況下我們是用平臺(tái)默認(rèn)設(shè)置的:
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
static class Android extends Platform { //我們一般都是Android平臺(tái)看這部分就行了
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor(); //可以看到,defaultCallbackExecutor()中new MainThreadExecutor()
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
//可以看到,這里實(shí)例化了一個(gè)獲取了主線程Looper的Handler,也就是說這個(gè)Handler實(shí)例是像主線程中發(fā)送消息的
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r); //采用Hanlder#post回調(diào)到主線程
}
}
}
④adapterFactories,這個(gè)對(duì)象主要用于對(duì)Call進(jìn)行轉(zhuǎn)化,基本上不需要我們自己去自定義。如果我們像最上面代碼中注釋掉的那樣添加一個(gè)addCallAdapterFactory(RxJavaCallAdapterFactory.create())
,那么就不會(huì)有下面的call.enqueue(new Call<List<Bean>>(){
這種的寫法了,直接轉(zhuǎn)換成RxJava那一套形式了。
⑤converterFactories,這個(gè)對(duì)象用于網(wǎng)絡(luò)請(qǐng)求轉(zhuǎn)換返回?cái)?shù)據(jù)的轉(zhuǎn)換。最開始那段示例代碼中,我們用的是GsonConverterFactory
,即Json數(shù)據(jù)解析,直接轉(zhuǎn)換成我們需要的List<Bean>
中的Bean實(shí)體類獨(dú)對(duì)象了。
??當(dāng)然,我們可以看到List<Converter.Factory> converterFactories
,即converterFactories是一個(gè)Converter.Factory類型的對(duì)象,對(duì)于Converter.Factory類來說,網(wǎng)絡(luò)請(qǐng)求轉(zhuǎn)換返回?cái)?shù)據(jù)的轉(zhuǎn)換只是我們最常用的一個(gè)功能,我們?nèi)绻此脑创a的話就會(huì)發(fā)現(xiàn),該接口類中有三個(gè)方法,也就是三種功能:
public Converter<ResponseBody, ?> responseBodyConverter()
用于將ResponseBody轉(zhuǎn)換為指定類型,通常用于對(duì)響應(yīng)結(jié)果的類型轉(zhuǎn)換。public Converter<?, RequestBody> requestBodyConverter()
用于將指定類型轉(zhuǎn)為RequestBody。一般用于將@Body,@Part,@PartMap轉(zhuǎn)為RequestBodypublic Converter<?, String> stringConverter()
用于將指定類型轉(zhuǎn)為String,用于將@Field,@FieldMap,@Path,@Query,@Header等注解的參數(shù)類型轉(zhuǎn)為String。
對(duì)于該接口類的用法我們?cè)谥蟮氖褂弥羞M(jìn)一步解釋。
OK,Build完之后,調(diào)用Retrofit構(gòu)造函數(shù),創(chuàng)建一個(gè)實(shí)例:
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = unmodifiableList(converterFactories); // Defensive copy at call site.
this.adapterFactories = unmodifiableList(adapterFactories); // Defensive copy at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
到這里Build模式創(chuàng)建Retrofit的準(zhǔn)備工作就完成了。
二.retrofit.create中動(dòng)態(tài)代理模式創(chuàng)建接口實(shí)例
Build完之后,就該Service service = retrofit.create(Service.class);
了:
public <T> T create(final Class<T> 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 {
......
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
這里出現(xiàn)了一個(gè)重量級(jí)的設(shè)計(jì)模式——?jiǎng)討B(tài)代理。好吧這個(gè)東西剛開始聽到的時(shí)候我感覺也挺嚇人的,遂研究之。關(guān)于動(dòng)態(tài)代理的詳細(xì)知識(shí)我們?cè)谶@里不詳細(xì)說明,不理解的話我們可以暫時(shí)把它理解成一個(gè)類/方法攔截器,我們?cè)?code>Service service = retrofit.create(Service.class);這句代碼中,我們通過create(Service.class)
這句代碼傳遞給了上面的源碼中的public <T> T create(final Class<T> service)
方法,Service.class也就是我們定義各種接口的方法:
public interface Service {
@GET("{username}")
Call<List<hot>> getBeanLists(@Path("username") String username);
}
因此,可以理解為,這里的(T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },new InvocationHandler()
就是攔截下了service.class這個(gè)類,public Object invoke(Object proxy, Method method, Object[] args)
就是在我們調(diào)用該類中的接口方法的時(shí)候,攔截下了我們所調(diào)用的方法,然后作進(jìn)一步處理。
??關(guān)于動(dòng)態(tài)代理,我們可以先做這樣一個(gè)狹隘的理解,我們重點(diǎn)要看的是上面代碼中的后三句代碼:
ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
我們接下來要有很長(zhǎng)的篇幅是圍繞這三句代碼展開的。
1.loadServiceMethod(method);
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method); //首先從map中取看看是否已經(jīng)緩存過
if (result != null) return result; //否則構(gòu)造ServiceMethod
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result); //緩存方法到map中
}
}
return result;
}
該方法傳入的method就是上面動(dòng)態(tài)代理的過程中攔截下的方法,也就是開頭我們的示例中getBeanLists()
方法。這里出現(xiàn)了一個(gè)ServiceMethod類,該類應(yīng)該是Retrofit源碼中最復(fù)雜的一個(gè)類了,它包含了將一個(gè)method轉(zhuǎn)化為Call的所有的信息。我們從這一句開始看result = new ServiceMethod.Builder<>(this, method).build();
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations(); //方法注解
this.parameterTypes = method.getGenericParameterTypes(); //參數(shù)類型
this.parameterAnnotationsArray = method.getParameterAnnotations(); //參數(shù)注解
}
public ServiceMethod build() {
callAdapter = createCallAdapter(); //創(chuàng)建CallAdapter,用來代理Call
responseType = callAdapter.responseType(); //返回的是我們方法的實(shí)際類型,例如:Call<User>,則返回User類型
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError("'" + Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
responseConverter = createResponseConverter(); //創(chuàng)建ResponseConverter,轉(zhuǎn)換ResponseBody為指定類型
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation); //遍歷解析方法注解
}
......
int parameterCount = parameterAnnotationsArray.length; //parameterAnnotationsArray為參數(shù)注解數(shù)組
parameterHandlers = new ParameterHandler<?>[parameterCount]; //初始化ParameterHandler,用來處理參數(shù)相關(guān)
for (int p = 0; p < parameterCount; p++) { //遍歷參數(shù)注解數(shù)組
Type parameterType = parameterTypes[p]; //獲取參數(shù)類型
......
Annotation[] parameterAnnotations = parameterAnnotationsArray[p]; //獲取參數(shù)注解數(shù)組
......
//通過注解和參數(shù)類型,解析并賦值到parameterHandlers中
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
......
return new ServiceMethod<>(this);
}
1).callAdapter的創(chuàng)建——createCallAdapter()
callAdapter 是Call方法的代理,把retrofit2.Call<T> 轉(zhuǎn)為 T(注意和 okhttp3.Call 區(qū)分開來,retrofit2.Call<T> 表示的是對(duì)一個(gè) Retrofit 方法的調(diào)用,也就是我們開始舉得例子中Call<List<Bean>> getBeanLists
的Call),這個(gè)過程會(huì)發(fā)送一個(gè) HTTP 請(qǐng)求,拿到服務(wù)器返回的數(shù)據(jù)(通過 okhttp3.Call 實(shí)現(xiàn)),并把數(shù)據(jù)轉(zhuǎn)換為聲明的 T 類型對(duì)象(通過 Converter<F, T> 實(shí)現(xiàn));
private CallAdapter<T, R> createCallAdapter() {
......
Annotation[] annotations = method.getAnnotations();
try {
return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create call adapter for %s", returnType);
}
}
可以看到調(diào)用了retrofit類中的callAdapter()方法:
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
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;
}
}
......
throw new IllegalArgumentException(builder.toString());
}
還記得adapterFactories嗎?
這里出現(xiàn)了一個(gè)adapterFactories變量,還記得這個(gè)變量嗎?好吧,你肯定忘了——這個(gè)就是我們開始舉得例子中,注釋掉的那一行//addCallAdapterFactory(RxJavaCallAdapterFactory.create()).
代碼所設(shè)置的東西,這里再貼一遍代碼:
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
adapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
如果我們不addCallAdapterFactory()方法的話,那么在Retrofit.build()方法中,系統(tǒng)會(huì)添加一個(gè)平臺(tái)默認(rèn)的值:
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
這里又出來了一個(gè)變量——callbackExecutor,同樣他也是我們之前說過的,向主線程中Post消息的回調(diào)線程池,忘了的同學(xué)可以回過頭去看一看,
??OK,示例代碼中我們注釋掉了addCallAdapterFactory(RxJavaCallAdapterFactory.create()),也就是沒有設(shè)置,那么這里應(yīng)該會(huì)添加平臺(tái)默認(rèn)的CallAdapterFactory,我們追蹤platform.defaultCallAdapterFactory(callbackExecutor)
最終到了ExecutorCallAdapterFactory類的public CallAdapter<?, ?> get()方法中,該方法最終返回了一個(gè)new ExecutorCallbackCall<>(callbackExecutor, call)
:
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
該ExecutorCallbackCall唯一做的事情就是將原本call的回調(diào)轉(zhuǎn)發(fā)至UI線程,因?yàn)?,我們之前說過,call.enqueue(new Call<List<Bean>>(){
是開啟一個(gè)異步線程。
回到nextCallAdapter()中
所以,CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
這句最終返回的就是“這個(gè)將原本call的回調(diào)轉(zhuǎn)發(fā)至UI線程的ExecutorCallbackCall”,createCallAdapter()同樣返回的是這個(gè)結(jié)果。
??通過上面的講解,我們可以知道,這個(gè)CallAdapterFactory實(shí)際上就是決定網(wǎng)絡(luò)請(qǐng)求回調(diào)方式的一個(gè)工廠。如果我們像之前注釋掉的代碼中的那樣,添加一個(gè)addCallAdapterFactory(RxJavaCallAdapterFactory.create())
,那么就會(huì)調(diào)用RxJava的回調(diào)方式返回結(jié)果,而不是默認(rèn)的call.enqueue(new Call<List<Bean>>(){
這種的。關(guān)于Retrofit和RxJava的配合使用,不在本文的討論范圍內(nèi)。
2).createResponseConverter()
responseConverter 是 Converter<ResponseBody, T> 類型,負(fù)責(zé)把服務(wù)器返回的數(shù)據(jù)(JSON、XML、二進(jìn)制或者其他格式,由 ResponseBody 封裝)轉(zhuǎn)化為 T 類型的對(duì)象。
??createResponseConverter()方法拿到的是responseConverter對(duì)象,它根據(jù)我們構(gòu)建retrofit時(shí),addConverterFactory()添加的ConverterFactory對(duì)象來尋找一個(gè)合適的返回,尋找的依據(jù)主要看該converter能否處理你編寫方法的返回值類型。
??什么意思?就是說,你在接收J(rèn)son文件的時(shí)候,需要根據(jù)后臺(tái)給你返回的Json格式來編寫實(shí)體類,這樣Gson()或者GsonConverterFactory.create()才能正確的解析數(shù)據(jù)成我們想要的實(shí)體類對(duì)象,否則就會(huì)轉(zhuǎn)換失敗。不過這個(gè)問題現(xiàn)在已經(jīng)不是很嚴(yán)重了,因?yàn)橛懈鞣N格式化Json數(shù)據(jù)的插件(如Android Studio 的GsonFormat插件),一般不會(huì)出錯(cuò)。
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);
}
}
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(Converter.Factory skipPast,
Type type, Annotation[] annotations) {
checkNotNull(type, "type == null");
checkNotNull(annotations, "annotations == null");
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;
}
}
......
throw new IllegalArgumentException(builder.toString());
}
這里我們貼了一遍源碼,可以看到,整個(gè)執(zhí)行的流程跟createCallAdapter()一模一樣。如果我們不指定addConverterFactory()這個(gè)參數(shù)的話,默認(rèn)實(shí)現(xiàn)為BuiltInConverters,僅僅支持返回值的實(shí)際類型為ResponseBody和Void,也就說明了默認(rèn)情況下,是不支持Call<User>這類類型的。關(guān)于BuiltInConverters我呢這里不展開說了,對(duì)本篇文章意義不大,有興趣自行看源碼。
3).遍歷解析方法注解——parseMethodAnnotation(annotation)
private void parseMethodAnnotation(Annotation annotation) {
/**請(qǐng)求方法注解**/
if (annotation instanceof DELETE) {
parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
} else if (annotation instanceof GET) {
parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
} else if (annotation instanceof HEAD) {
parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
if (!Void.class.equals(responseType)) {
throw methodError("HEAD method must use Void as response type.");
}
} else if (annotation instanceof PATCH) {
parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
} else if (annotation instanceof POST) {
parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
} else if (annotation instanceof PUT) {
parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
} else if (annotation instanceof OPTIONS) {
parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
} else if (annotation instanceof HTTP) {
/**自定義HTTP請(qǐng)求注解**/
HTTP http = (HTTP) annotation;
parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
} else if (annotation instanceof retrofit2.http.Headers) {
/**請(qǐng)求頭注解**/
String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
if (headersToParse.length == 0) {
throw methodError("@Headers annotation is empty.");
}
headers = parseHeaders(headersToParse);
} else if (annotation instanceof Multipart) {
/**FormUrlEncoded**/
if (isFormEncoded) {
throw methodError("Only one encoding annotation is allowed.");
}
isMultipart = true;
} else if (annotation instanceof FormUrlEncoded) {
/**Multipart**/
if (isMultipart) {
throw methodError("Only one encoding annotation is allowed.");
}
isFormEncoded = true;
}
}
解析請(qǐng)求方法注解和路徑參數(shù)——parseHttpMethodAndPath()
該方法主要用于解析我們?cè)O(shè)置的方法頂部的網(wǎng)絡(luò)請(qǐng)求方式注解,如GET,POST等(@GET("{username}")
),先判斷是那種請(qǐng)求方式(上面的代碼中已經(jīng)判斷完了),完了之后再具體解析請(qǐng)求方法中的路徑參數(shù)。
??這里復(fù)習(xí)一下,Http協(xié)議的URL格式為:schema://host[:port#]/path/.../[;url-params][?query-string][#anchor]
,“?”前面(準(zhǔn)確的說是從域名后的第一個(gè)“/”開始到最后一個(gè)“/”為止)是訪問資源的路徑,從“?”開始到“#”為止,為參數(shù)部分,又稱搜索部分、查詢部分,參數(shù)與參數(shù)之間用“&”作為分隔符。,忘了的同學(xué)可以參照我的這篇文章:HTTP協(xié)議詳解與Android相關(guān)基礎(chǔ)網(wǎng)絡(luò)編程
??在Retrofit中訪問zhy的信息的兩種形式:
http://baseurl/user/zhy
public interface IUserBiz{
@GET("{username}")
Call<User> getUser(@Path("username") String username);
}
而 http://baseurl/users?sortby=username
public interface IUserBiz{
@GET("users")
Call<List<User>> getUsersBySort(@Query("sortby") String sort);
}
也即是說,對(duì)于接口方法中的注解參數(shù)來說,@Path()仍然對(duì)應(yīng)的是BASE_URL的自路徑,@Query()對(duì)應(yīng)的才是“?”后面的參數(shù)查詢。忘了的同學(xué)可以參照鴻陽大神的這篇文章:Retrofit2 完全解析 探索與okhttp之間的關(guān)系
回到parseHttpMethodAndPath()源碼中:
int question = value.indexOf('?'); //查詢參數(shù)開始的符號(hào),“?”之后是查詢的參數(shù)部分,“?”之前是查詢的路徑部分
if (question != -1 && question < value.length() - 1) {
String queryParams = value.substring(question + 1); //截取"?"之前的路徑部
Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams); //如果在“?”之前的路徑參數(shù)中使用了{(lán)},則拋出異常。
if (queryParamMatcher.find()) {
throw methodError("URL query string \"%s\" must not have replace block. "
+ "For dynamic query parameters use @Query.", queryParams);
}
}
this.relativeUrl = value;
this.relativeUrlParamNames = parsePathParameters(value); //解析{}路徑參數(shù)保存到Set中
static final String PARAM = "[a-zA-Z][a-zA-Z0-9_-]*";
static final Pattern PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}");
可以看到,這個(gè)方法就是解析路徑參數(shù),如果有“?”就把“?”之前的部分截取出來加以判斷,如果這部分路徑中有“{}”占位符,則拋出異常,讓你用@Query()標(biāo)簽動(dòng)態(tài)添加。
??最后一句this.relativeUrlParamNames = parsePathParameters(value);
,這一句中parsePathParameters(value)
這個(gè)方法主要就是解析“{}”中所包含的參數(shù),然后存到一個(gè)set<>集合中,保存在relativeUrlParamNames這個(gè)全局變量中。
4).解析每個(gè)參數(shù)使用的注解類型(諸如 Path,Query等)——ParameterHandler
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
if (Utils.hasUnresolvableType(parameterType)) {
throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
parameterType);
}
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
if (parameterAnnotations == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
每個(gè)參數(shù)都會(huì)有一個(gè) ParameterHandler,由 ServiceMethod#parseParameter 方法負(fù)責(zé)創(chuàng)建,其主要內(nèi)容就是解析每個(gè)參數(shù)使用的注解類型(諸如 Path,Query,F(xiàn)ield 等),對(duì)每種類型進(jìn)行單獨(dú)的處理。
??上面代碼中,我們直接從最后一句看起:parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
這句主要就是將每個(gè)方法中的參數(shù)解析成一個(gè)parameterHandlers[]數(shù)組儲(chǔ)存:
private ParameterHandler<?> parseParameter(
int p, Type parameterType, Annotation[] annotations) {
ParameterHandler<?> result = null;
for (Annotation annotation : annotations) {
ParameterHandler<?> annotationAction = parseParameterAnnotation(
p, parameterType, annotations, annotation);
......
result = annotationAction;
}
......
return result;
}
可以看到parseParameter方法中主要調(diào)用的是parseParameterAnnotation()方法來構(gòu)建ParameterHandler對(duì)象,關(guān)于這個(gè)parseParameterAnnotation()方法由于源碼是在是太長(zhǎng)了(370+行代碼),所以我們不貼出來,主要知道他做了哪幾件事情就行:
??首先根據(jù)注解來判斷來校驗(yàn)使用上有沒有錯(cuò)誤,比如@Query注解必須在@Path和@Url后使用,使用了@Url注解那么請(qǐng)求方法注解中不允許設(shè)置請(qǐng)求路徑等等;然后獲取相應(yīng)Converter用于轉(zhuǎn)換類型(String,ResponseBody),最后初始化相應(yīng)ParameterHandler返回。
好了到這里我們第二大點(diǎn)二.retrofit.create中動(dòng)態(tài)代理模式創(chuàng)建接口實(shí)例中三句重點(diǎn)代碼中的第一句loadServiceMethod()方法,中的ServiceMethod.build()就講完了,為了避免大家迷失在茫茫的細(xì)節(jié)當(dāng)中,我們?cè)僭谶@里帖一遍本篇的提綱:
并再帖一遍代碼:
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;
}
public ServiceMethod build() {
......
return new ServiceMethod<>(this);
}
這里我們還是要說一下這個(gè)build()方法最終Return的結(jié)果,也就是ServiceMethod()的構(gòu)造函數(shù):
ServiceMethod(Builder<R, T> builder) {
this.callFactory = builder.retrofit.callFactory(); //callFactory,默認(rèn)為okhttp3.OkHttpClient
//callAdapter,指定Retrofit.call網(wǎng)絡(luò)請(qǐng)求的回調(diào)式,默認(rèn)為ExecutorCallbackCall對(duì)象,也就是文章最開頭
//示例中的call.enqueue(new Call<List<Bean>>(){,當(dāng)然我們可以指定為我們想要的的形式,如RxJava
this.callAdapter = builder.callAdapter;
this.baseUrl = builder.retrofit.baseUrl();//BASE_URL沒什么好說的
//responseConverter,負(fù)責(zé)轉(zhuǎn)化服務(wù)器返回的數(shù)據(jù)成我們想要的實(shí)體對(duì)象,如果返回的是Json數(shù)據(jù)的話一般用Gson解析
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;
//parameterHandlers,包裝API 定義時(shí)每個(gè)方法的參數(shù)(諸如 Path,Query等),并在構(gòu)造 HTTP 請(qǐng)求時(shí)設(shè)置參數(shù)
this.parameterHandlers = builder.parameterHandlers;
}
這個(gè)構(gòu)造函數(shù)中包含了ServiceMethod類的各種實(shí)例變量,這里我們需要重點(diǎn)注意幾個(gè)變量:callFactory,callAdapter,responseConverter,parameterHandlers,這四個(gè)變量我們之前都有過詳細(xì)的講解,可以結(jié)合注釋復(fù)習(xí)一下。
2.構(gòu)建OkHttpCall()
我們這里再帖一遍我們說過的那三句重點(diǎn)的代碼:
ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
經(jīng)過上面的分析,我們應(yīng)該知道這個(gè)serviceMethod實(shí)際上就是一個(gè)包含了我們網(wǎng)絡(luò)請(qǐng)求的callFactory,callAdapter,responseConverter,parameterHandlers等重要信息的一個(gè)對(duì)象。接下來我們看第二句代碼:
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
這句中實(shí)例化一個(gè)okHttpCall對(duì)象,構(gòu)造函數(shù)僅僅是簡(jiǎn)單的賦值:
OkHttpCall(ServiceMethod<T, ?> serviceMethod, Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
接下來看第三句代碼return serviceMethod.callAdapter.adapt(okHttpCall);
,這句代碼中的serviceMethod.callAdapter,也就是我們?cè)?.1中講的callAdapter,如何返回回調(diào)值的參數(shù)。經(jīng)過上面的分析,假設(shè)我們這里沒有指定addCallAdapterFactory(RxJavaCallAdapterFactory.create())
這個(gè)參數(shù),那么我們這里的callAdapter就是默認(rèn)的CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
。
??而這個(gè)adapterFactories是ExecutorCallAdapterFactory類的對(duì)象,我們?nèi)ピ擃愔锌聪?
代碼2.2(1)
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
//看這里看這里,這里重寫了get方法,也就是默認(rèn)的CallAdapter<?, ?> adapter =
//apterFactories.get(i).get(returnType, annotations, this);中的get()方法
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 serviceMethod.callAdapter.adapt(okHttpCall);中的adapt()代碼
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
調(diào)用new ExecutorCallbackCall<>(callbackExecutor, call)
,這個(gè)類我們將在下節(jié)中講解。
??這兩個(gè)步驟都是之前講過的,建議大家回過頭去看下(好吧我寫到這里都有點(diǎn)忘了之前寫過)。也就是說,ExecutorCallbackCall僅僅是對(duì)Call對(duì)象進(jìn)行封裝,類似裝飾者模式,只不過將其執(zhí)行時(shí)的回調(diào)通過callbackExecutor進(jìn)行回調(diào)到UI線程中去了。
三.發(fā)起網(wǎng)絡(luò)請(qǐng)求
首先我們?cè)儋N一遍文章開頭的示例代碼:
Retrofit retrofit = new Retrofit.Builder().
baseUrl(BASE_URL).
//addCallAdapterFactory(RxJavaCallAdapterFactory.create()).
addConverterFactory(GsonConverterFactory.create()).
build();
Service service = retrofit.create(Service.class);
Call<List<Bean>> call = service.getBeanLists(“username”);
call.enqueue(new Call<List<Bean>>(){
@Override
public void onResponse(Call<List<Bean>> call, Response<List<Bean>> response) {
beanList = response.body();
... //doSomething();
}
@Override
public void onFailure(Call<List<hot>> call, Throwable t) {
Toast.makeText(getContext(), "讀取失敗,請(qǐng)檢查網(wǎng)絡(luò)設(shè)置", Toast.LENGTH_SHORT).show();
}
});
public interface Service {
@GET("{username}")
Call<List<Bean>> getBeanLists(@Path("username") String username);
}
經(jīng)過我們上述的講解,Retrofit底層的基礎(chǔ)設(shè)施基本就講完了,現(xiàn)在我們來發(fā)起一個(gè)網(wǎng)絡(luò)請(qǐng)求。嗯,網(wǎng)絡(luò)請(qǐng)求是在哪里發(fā)起的呢?實(shí)際上只要我們執(zhí)行了Call<List<Bean>> call = service.getBeanLists(“username”);
這一句之后,網(wǎng)絡(luò)請(qǐng)求就開始了,然后我們只需要在call.enqueue(new Call<List<Bean>>(){
中等著回調(diào)參數(shù)就行了。
我們這里要講的是,網(wǎng)絡(luò)請(qǐng)求的數(shù)據(jù),是如何下發(fā)到我們重寫的
call.enqueue(new Call<List<Bean>>(){
@Override
public void onResponse(Call<List<Bean>> call, Response<List<Bean>> response) {
}
@Override
public void onFailure(Call<List<hot>> call, Throwable t) {
}
});
中來的?
1.從ExecutorCallAdapterFactory到OkHttpCall
首先我們得接著上一節(jié)“構(gòu)建OkHttpCall()”中代碼2.2(1)說起,我們說過,代碼2.2(1)中實(shí)現(xiàn)了示例代碼中“retrofit.create(HotService.class);”這句對(duì)應(yīng)的源碼中,三句關(guān)鍵代碼的第三句return serviceMethod.callAdapter.adapt(okHttpCall);
這句代碼,我們把這個(gè)類的代碼再貼一遍,這次順便帶上ExecutorCallbackCall這個(gè)靜態(tài)內(nèi)部類:
ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
代碼3.1(1)
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
......(省略部分代碼2.2(1)中的內(nèi)容)
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
@Override public Call<Object> adapt(Call<Object> call) {
//我們說過,這里重寫的adapt()就是三句關(guān)鍵代碼中第三就的adapt,也即是說,這里的參數(shù)Call<Object> call
//就是第二句中構(gòu)建的OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
//這個(gè)callbackExecutor就是一個(gè)線程池對(duì)象,用來開啟異步線程,沒有什么好說的
this.callbackExecutor = callbackExecutor;
//在ExecutorCallbackCall類的構(gòu)造函數(shù)中,又將okHttpCall對(duì)象遞給delegate對(duì)象
this.delegate = delegate;
}
@Override
public void enqueue(final Callback<T> callback) { (enqueue.1)
if (callback == null) throw new NullPointerException("callback == null");
//delegate是一個(gè)OkHttpCall類的對(duì)象,這一點(diǎn)要明確
delegate.enqueue(new Callback<T>() { (enqueue.2)
@Override
public void onResponse(Call<T> call, final Response<T> response) { (onResponse.1)
callbackExecutor.execute(new Runnable() {
@Override
public void run() {
if (delegate.isCanceled()) {
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled")); (onFailure.1)
} else {
callback.onResponse(ExecutorCallbackCall.this, response); (onResponse.2)
}
}
});
}
@Override
public void onFailure(Call<T> call, final Throwable t) { (onFailure.2)
callbackExecutor.execute(new Runnable() {
@Override
public void run() {
callback.onFailure(ExecutorCallbackCall.this, t); (onFailure.1)
}
});
}
});
}
為什么要貼這么一串又臭又長(zhǎng)的源碼呢?可以看到上面的代碼中我們標(biāo)出了2個(gè)enqueue()方法,2個(gè)onResponse()方法,3個(gè)onFailure()方法~~好吧我剛開始看也看懵逼了,后來才發(fā)現(xiàn),這里有兩個(gè)接口在嵌套使用,所以必須對(duì)照源碼才能說的清楚。
2個(gè)enqueue()方法
我們要分清楚這兩個(gè)enqueue()方法都是干什么的。首先我們看(enqueue.1)處的這個(gè)enqueue方法,可以看到他是@Override,即重寫的方法,重寫的誰的呢?當(dāng)然是ExecutorCallbackCall類實(shí)現(xiàn)的Call<T>中的方法,這里需要注意一點(diǎn),這里的Call<T>是retrofit2.call<T>,不要和待會(huì)出現(xiàn)的okhttp3.Call搞混了。
??我們?cè)賮砜?strong>(enqueue.2)處的enqueue,這個(gè)enqueue是由delegate調(diào)用的,我們之前強(qiáng)調(diào)過,delegate是OkHttpCall類的對(duì)象,也就是說,這里的enqueue(new Callback<T>() {
實(shí)際上是OkHttpCall類中傳過來的,我們進(jìn)入到該類中,看看該類中的enqueue()方法(retrofit-2.2.0-source.jar/retrofit2/OkHttpCall):
代碼3.1(2)
public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
call = rawCall = createRawCall(); //createRawCall()方法創(chuàng)建原始Call,即okhttp3.Call對(duì)象
} catch (Throwable t) {
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
call.enqueue(new okhttp3.Callback() { //調(diào)用okhttp3.Call發(fā)起一個(gè)enqueue()異步請(qǐng)求
//注意這里的enqueue()方法是OkHttp中的"真"異步請(qǐng)求方法,前面的都是自定義的"假"方法
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) (onResponse.4)
throws IOException {
Response<T> response;
try {
response = parseResponse(rawResponse); //解析服務(wù)器返回的內(nèi)容,生成response對(duì)象
} catch (Throwable e) {
callFailure(e);
return;
}
callSuccess(response);
}
@Override
public void onFailure(okhttp3.Call call, IOException e) { (onFailure.4)
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callFailure(Throwable e) {
try {
//這里通過callBack將錯(cuò)誤結(jié)果返回給ExecutorCallbackCall類
callback.onFailure(OkHttpCall.this, e); (onFailure.3)
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callSuccess(Response<T> response) {
try {
//這里通過callback回調(diào)接口將網(wǎng)絡(luò)請(qǐng)求并解析后的結(jié)果返回給ExecutorCallbackCall類
callback.onResponse(OkHttpCall.this, response); (onResponse.3)
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}
OkHttpCall類中的enqueue()方法很簡(jiǎn)單,實(shí)際上就是先創(chuàng)建一個(gè)okhttp3.Call對(duì)象,然后利用這個(gè)okhttp3.Call發(fā)起一個(gè)異步請(qǐng)求,完了時(shí)候講返回的結(jié)果通過callback接口返回給ExecutorCallbackCall類。
??我們需要注意這里的調(diào)用關(guān)系:
3.1(1)
delegate.enqueue(new Callback<T>() {
3.1(2)
public void enqueue(final Callback<T> callback) {
也就是說,代碼3.1(1)中(enqueue.2)處的new Callback,就是我們代碼3.1(2)中的參數(shù)final Callback<T> callback,所以我們?cè)诖a3.1(2)中的(onFailure.3),(onResponse.3)都會(huì)通過這個(gè)callback實(shí)例回調(diào)到代碼3.1(2)中的(onResponse.1)和(onFailure.2),這個(gè)對(duì)應(yīng)關(guān)系一定要看清楚。
??我們?cè)購?qiáng)調(diào)一遍,代碼3.1(2)中的(onResponse.1)和(onFailure.2)兩個(gè)@Override類型的方法,它們是OkHttpCall類(3.1(2))中(onFailure.3)和(onResponse.3)兩處的方法,的回調(diào)?。?!
??而OkHttpCall類(3.1(2))中(onFailure.4)和(onResponse.4)兩處重寫的方法,它們重寫的是call.enqueue(new okhttp3.Callback() {
這個(gè)OkHttp異步請(qǐng)求的接口的,onFailure和onResponse方法,表示OkHttp網(wǎng)絡(luò)請(qǐng)求的結(jié)果。
??是不是感覺腦子暈暈的?沒錯(cuò),不知道Squareup為什么這段代碼寫的可讀性這么差~~~嗯,更精彩的還在后面,這里假設(shè)你已經(jīng)理解了上面這幾個(gè)長(zhǎng)的一模一樣但是卻代表不同意義的幾個(gè)方法和回調(diào)。
回到ExecutorCallAdapterFactory(3.1(1))類中,如果你已經(jīng)理解了上面所說的話,就應(yīng)該知道,(onResponse.1)和(onFailure.2)這兩個(gè)重寫方法,是OkHttpCall類(3.1(2))中OkHttp的異步網(wǎng)絡(luò)請(qǐng)求所回調(diào)回來的結(jié)果。我們?cè)儋N一下代碼:
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
......
@Override
public void enqueue(final Callback<T> callback) { (enqueue.1)
if (callback == null) throw new NullPointerException("callback == null");
//delegate是一個(gè)OkHttpCall類的對(duì)象,這一點(diǎn)要明確
delegate.enqueue(new Callback<T>() { (enqueue.2)
@Override
public void onResponse(Call<T> call, final Response<T> response) { (onResponse.1)
callbackExecutor.execute(new Runnable() {
@Override
public void run() {
if (delegate.isCanceled()) {
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled")); (onFailure.1)
} else {
callback.onResponse(ExecutorCallbackCall.this, response); (onResponse.2)
}
}
});
}
@Override
public void onFailure(Call<T> call, final Throwable t) { (onFailure.2)
callbackExecutor.execute(new Runnable() {
@Override
public void run() {
callback.onFailure(ExecutorCallbackCall.this, t); (onFailure.1)
}
});
}
});
}
我們?cè)賮砜纯催@個(gè)(onFailure.1)和(onResponse.2)這兩種方法,這里有出現(xiàn)了一個(gè)callback,這里的callback又是什么呢?Ok,如果你看源碼的化就會(huì)發(fā)現(xiàn),這個(gè)Callback是(enqueue.1)處:
@Override
public void enqueue(final Callback<T> callback) {
這個(gè)重寫的enqueue()的參數(shù),我們之前說過,這里的enqueue重寫的是Call<T>接口中的方法,因?yàn)?code>ExecutorCallbackCall<T> implements Call<T>,而另一端回調(diào)這個(gè)Call<T>
接口的地方,是在我們縮寫的代碼中:
call.enqueue(new Call<List<Bean>>(){
@Override
public void onResponse(Call<List<Bean>> call, Response<List<Bean>> response) {
}
@Override
public void onFailure(Call<List<hot>> call, Throwable t) {
}
});
看到了吧?(onFailure.2)和(onResponse.2)這兩處的callback回調(diào),最終回調(diào)到了我們所寫的call.enqueue(new Call<List<Bean>>(){
中,并且攜帶著已經(jīng)轉(zhuǎn)換成我們想要的特定實(shí)體類型的數(shù)據(jù)。
??到這里,我們已經(jīng)拿到了我們想要的數(shù)據(jù),整個(gè)分析的過程也就走完了。