本平臺的文章更新會有延遲,你們能夠關注微信公衆號-顧林海,包括年末前會更新kotlin由淺入深系列教程,目前計劃在微信公衆號進行首發,若是你們想獲取最新教程,請關注微信公衆號,謝謝!java
在上章節《Android小知識-剖析Retrofit中的網絡請求流程以及相關參數》中介紹了Retrofit的成員變量,以及靜態內部類Builder中的成員變量,本節繼續講解Builder類中的相關方法。web
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://icould.glh/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
複製代碼
經過Builder的baseUrl方法來設置http的基地址,先進入baseUrl方法。json
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}
複製代碼
在baseUrl方法中,將傳入的String類型的baseUrl經過HttpUrl的parse方法轉換成HttpUrl對象,將轉換後的httpUrl實例傳入baseUrl方法,注意這裏傳入baseUrl方法的是HttpUrl對象,咱們繼續看baseUrl(HttpUrl)方法。數組
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
List<String> pathSegments = baseUrl.pathSegments();
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
複製代碼
經過checkNotNull方法判斷HttpUrl對象是否爲空,接着經過HttpUrl的pathSegments()方法將url拆分紅多個獨立的碎片,爲了方便比較,將建立Retrofit實例貼出來:服務器
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://icould.glh/")
複製代碼
經過baseUrl方法設置http的url時,在最後是以'/'反斜槓結尾的,下面的if語句中判斷拆分後的最後字符串是否爲空,拆分後的數組最後一個爲空,說明http的url是以'/'結尾,反之http的url不是以'/'結尾,就會拋出異常,最後將baseUrl賦值給Builder的成員變量baseUrl。微信
介紹完baseUrl方法,繼續看下一個方法addConverterFactory方法:網絡
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://icould.glh/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
複製代碼
addConverterFactory方法是用於設置數據解析器,進入addConverterFactory方法看看到底作了哪些操做。ide
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
複製代碼
addConverterFactory方法所作的工做很簡單,就是將factory添加到數據解析器工廠的集合中。回到前面addConverterFactory方法,看到傳入的是GsonConverterFactory對象,而GsonConverterFactory對象是經過GsonConverterFactory的get()方法建立的,點進去看下。函數
public static GsonConverterFactory create() {
return create(new Gson());
}
複製代碼
create方法內部先是建立了Gson對象,這個Gson就是goole提供的Gson,用於解析json數據用的,建立完Gson對象後調用create方法並傳入剛建立後的Gson對象。ui
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new GsonConverterFactory(gson);
}
複製代碼
方法很簡單,建立一個GsonConverterFactory對象並返回,咱們進入GsonConverterFactory的構造函數中。
private final Gson gson;
private GsonConverterFactory(Gson gson) {
this.gson = gson;
}
複製代碼
GsonConverterFactory的構造函數只作了賦值操做,將建立好的Gson對象賦值給GsonConverterFactory的成員變量gson。
介紹完addConverterFactory方法後,接着看addCallAdapterFactory方法:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://icould.glh/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
複製代碼
addCallAdapterFactory方法用於設置適配的平臺,這裏使用的是RxJava平臺,咱們看下addCallAdapterFactory的具體操做。
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
callAdapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
複製代碼
代碼仍是很簡單,就是將factory添加到適配器工廠的集合中去。回到前面,看看addCallAdapterFactory方法傳入的這個Factory,是經過RxJavaCallAdapterFactory工廠類的create()方法來建立的。
public static RxJavaCallAdapterFactory create() {
return new RxJavaCallAdapterFactory(null, false);
}
複製代碼
create方法內部直接經過new關鍵字建立了RxJavaCallAdapterFactory對象。
public final class RxJavaCallAdapterFactory extends CallAdapter.Factory {
...
}
複製代碼
RxJavaCallAdapterFactory繼承了CallAdapter的內部類Factory。
先看CallAdapter的做用,CallAdapter做用就是經過Retrofit中Call轉換成Java對象,Retrofit中的Call對象和OkHttp中的Call對象是不同的,Retrofit中的Call是對OkHttp中的Call進行了封裝,也就是說經過Retrofit來進行網絡請求,最終都是經過OkHttp來進行請求的。在轉換Java對象前,須要先建立Retrofit中的Call對象,而後經過Call對象發送http請求,服務器會返回響應的數據,這個時候經過converter數據轉換器,將服務器返回的Response轉換成咱們須要的Java對象。
public interface CallAdapter<R, T> {
Type responseType();
T adapt(Call<R> call);
}
複製代碼
在CallAdapter接口中定義了一個responseType()方法並返回Type類型,這個方法的做用就是返回解析後的類型。看下面網絡請求接口:
public interface NetworkInterface {
@GET("news/newsDetail")
Call<MyResponse> getNewsDetails(@QueryMap Map<String,String> map);
}
複製代碼
CallAdapter接口中的responseType方法返回的就是MyResponse這個類型的對象。
public interface CallAdapter<R, T> {
Type responseType();
T adapt(Call<R> call);
}
複製代碼
繼續看第二個方法adapt,這裏的泛型T是指須要轉換接口的返回類型,adapt方法傳入一個Call對象,這個Call對象就是OkHttp的Call對象,若是對應的是RxJava的話,這裏的T對應的就是RxJava當中的類型。
繼續看CallAdapter內部類Factory:
public interface CallAdapter<R, T> {
...
abstract class Factory {
public abstract @Nullable retrofit2.CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
Retrofit retrofit);
...
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}
複製代碼
get方法的做用是根據接口的返回類型以及註解類型來獲得實際須要的CallAdapter;getRawType方法返回的是原始的類型。
RxJavaCallAdapterFactory實現Factory抽象類,用來提供具體的適配邏輯,回到RxJavaCallAdapterFactory,先看get方法的實現:
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
...
return new RxJavaCallAdapter(responseType, scheduler, isAsync, isResult, isBody, isSingle,
false);
}
複製代碼
在get方法中,先經過getRawType拿到原始數據類型,經過這個原始數據類型進行各類設置,最後建立RxJavaCallAdapter對象並返回。建立完RxJavaCallAdapter對象後,最終調用adapt方法將咱們的Call請求轉換成每個平臺所適用的類型。adapt方法在接口CallAdapter中定義的,在源碼中找到RxJavaCallAdapter實現了CallAdapter接口,咱們看看RxJavaCallAdapter中的adapt實現。
@Override public Object adapt(Call<R> call) {
Observable.OnSubscribe<Response<R>> callFunc = isAsync
? new CallEnqueueOnSubscribe<>(call)
: new CallExecuteOnSubscribe<>(call);
Observable.OnSubscribe<?> func;
if (isResult) {
func = new ResultOnSubscribe<>(callFunc);
} else if (isBody) {
func = new BodyOnSubscribe<>(callFunc);
} else {
func = callFunc;
}
Observable<?> observable = Observable.create(func);
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isSingle) {
return observable.toSingle();
}
if (isCompletable) {
return observable.toCompletable();
}
return observable;
}
複製代碼
使用過RxJava的同窗應該對上面的代碼很是熟悉了,將咱們傳入的OkHttp的Call對象設置給OnSubscribe對象,接着建立Observable被觀察者的實例,並將OnSubscribe與被觀察者綁定,最後判斷scheduler調度器是否爲空,若是不爲空,就調用observable的subscribeOn方法在指定的調度器執行操做。關於RxJava的相關知識後面會另開文章進行講解,這裏你們先有個印象,知道總體的流程便可。
到這裏baseUrl、addConverterFactory以及addCallAdapterFactory方法就介紹完畢。
搜索微信「顧林海」公衆號,按期推送優質文章。