Retrofit源碼解讀(二)--Retrofit中網(wǎng)絡(luò)通信相關(guān)
標(biāo)簽(空格分隔): Retrofit源碼 學(xué)習(xí)筆記
網(wǎng)絡(luò)通信八步走
1、創(chuàng)建Retrofit實(shí)例
2、定義一個網(wǎng)絡(luò)請求接口并對接口中的方法添加注解
3、通過 動態(tài)代理 生成網(wǎng)絡(luò)請求對象
4、通過網(wǎng)絡(luò)請求適配器,將網(wǎng)絡(luò)請求對象進(jìn)行平臺適配
5、通過網(wǎng)絡(luò)請求執(zhí)行器,發(fā)送網(wǎng)絡(luò)請求
6、通過數(shù)據(jù)轉(zhuǎn)換器,解析服務(wù)器返回的數(shù)據(jù)
7、通過回調(diào)執(zhí)行器,切換線程
8、用戶在主線程編寫邏輯
創(chuàng)建Retrofit實(shí)例
public static Retrofit getRetrofit() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(10, TimeUnit.SECONDS);
return new Retrofit.Builder()
.client(builder.build())
.baseUrl("http://m2.qiushibaike.com/") //設(shè)置請求網(wǎng)絡(luò)地址的url(基地址 這個地址一定要"/"結(jié)尾 要不會出現(xiàn)問題)
.addConverterFactory(GsonConverterFactory.create()) //設(shè)置數(shù)據(jù)解析器 默認(rèn)使用的Gson
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) //設(shè)置支持RxJava轉(zhuǎn)換器
.build();
}
Retrofit的成員變量
//map對象,key值是Method 請求方法,value值是ServiceMethod 主要代表我們的網(wǎng)絡(luò)請求方法進(jìn)行注解之后的解析使用
//serviceMethodCache 用于緩存網(wǎng)絡(luò)請求配置,方法,數(shù)據(jù)轉(zhuǎn)換器 適配器
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
//請求網(wǎng)絡(luò)的okhttp工廠 默認(rèn)的就是這個
final okhttp3.Call.Factory callFactory;
//請求基地址
final HttpUrl baseUrl;
//數(shù)據(jù)轉(zhuǎn)換器工廠集合 用于數(shù)據(jù)請求得到的response進(jìn)行轉(zhuǎn)換
final List<Converter.Factory> converterFactories;
//網(wǎng)絡(luò)請求適配器工廠集合 比如RxJava的call
final List<CallAdapter.Factory> adapterFactories;
//回調(diào)執(zhí)行器 默認(rèn)的是MainThreadExecutor
final @Nullable Executor callbackExecutor;
//標(biāo)志位 是否需要立即解析接口中的方法 后面解析的時候會看到
final boolean validateEagerly;
Builder內(nèi)部類
內(nèi)部類中的成員變量
//平臺 ios android java8
private final Platform platform;
//請求網(wǎng)絡(luò)的okhttp工廠 默認(rèn)的就是這個
private @Nullable okhttp3.Call.Factory callFactory;
//請求基地址 需要轉(zhuǎn)換的
private HttpUrl baseUrl;
//數(shù)據(jù)轉(zhuǎn)換器工廠集合 用于數(shù)據(jù)請求得到的response進(jìn)行轉(zhuǎn)換
private final List<Converter.Factory> converterFactories = new ArrayList<>();
//網(wǎng)絡(luò)請求適配器工廠集合 比如RxJava的call
private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
//回調(diào)執(zhí)行器 默認(rèn)的是MainThreadExecutor
private @Nullable Executor callbackExecutor;
//標(biāo)志位 是否需要立即解析接口中的方法 后面解析的時候會看到
private boolean validateEagerly;
可以看到這個內(nèi)部類的成員變量和retrofit的成員變量是一樣的,因?yàn)檫@個是建造者模式,對于一些的添加的變量和外部類是一樣的。構(gòu)建者模式就是通過這些配置,將一些成員變量進(jìn)行初始化
Builder無參數(shù)構(gòu)造方法
public Builder() {
this(Platform.get());
}
可以看出Platform 這個類是個單例 通過findPlatform()方法獲取到這個單例
其中的get()方法就是findPlatform()的方法
在這個方法里面,通過反射來獲取類名,在安卓中就是返回new Android()
//也就是下方的這個Android類
static class Android extends Platform {
//會有一個默認(rèn)的回調(diào)執(zhí)行器MainThreadExecutor Looper.getMainLooper() 也就是主線程
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
//創(chuàng)建默認(rèn)的網(wǎng)絡(luò)請求適配器工廠 創(chuàng)建默認(rèn)的網(wǎng)絡(luò)請求適配器回調(diào)
//這個默認(rèn)請求工廠產(chǎn)生的calladapter讓我們的call請求在異步調(diào)用的時候會指定我們的Executor執(zhí)行器 讓他執(zhí)行回調(diào)
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
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);
}
}
}
Builder有參數(shù)構(gòu)造方法
Builder(Platform platform) {
//做好Platform的初始化
this.platform = platform;
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
//在數(shù)據(jù)轉(zhuǎn)換工廠集合中添加一個內(nèi)置的BuiltInConverters對象 也就是說如果當(dāng)我們沒有添加或者沒有指定數(shù)據(jù)轉(zhuǎn)換工廠(一般會指定為GsonConverterFactory為我們的數(shù)據(jù)轉(zhuǎn)換工廠)
converterFactories.add(new BuiltInConverters());
}
由此我們可以看出來,Builder這個內(nèi)部類主要是構(gòu)建了我們的使用平臺,配置了數(shù)據(jù)轉(zhuǎn)換器工廠(默認(rèn)),網(wǎng)絡(luò)適配器的工廠,以及我們的Ececutor(默認(rèn)值的初始化),這個地方還沒有真正的配置到retrofit的成員變量中。
baseUrl(string) 方法
public Builder baseUrl(String baseUrl) {
//工具類檢測我們傳入的url是否為空
checkNotNull(baseUrl, "baseUrl == null");
//通過parse方法將String類型的Url轉(zhuǎn)換為HttpUrl類型的成員變量
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
//最后通過baseUrl()這個方法來返回Builder這個類型
return baseUrl(httpUrl);
}
//
public Builder baseUrl(HttpUrl baseUrl) {
//判空處理
checkNotNull(baseUrl, "baseUrl == null");
//拆分成多個片段
List<String> pathSegments = baseUrl.pathSegments();
//判斷集合中的最后一個是否以“/”結(jié)尾
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
//在這里可以看出來傳入的url必須以 “/” 結(jié)尾
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
addConverterFactory()方法
/** Add converter factory for serialization and deserialization of objects. */
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
我們來看下我們傳入的Factory這個對象GsonConverterFactory
因?yàn)槲覀兪峭ㄟ^GsonConverterFactory.create()方法傳入的
public static GsonConverterFactory create() {
//創(chuàng)建Gson對象
return create(new Gson());
}
public static GsonConverterFactory create(Gson gson) {
return new GsonConverterFactory(gson);
}
private GsonConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
//將傳入的gson對象賦值給我們GsonConverterFactory里面創(chuàng)建的gson成員變量
this.gson = gson;
}
addCallAdapterFactory()方法
/**
* 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()
public static RxJavaCallAdapterFactory createWithScheduler(Scheduler scheduler) {
if (scheduler == null) throw new NullPointerException("scheduler == null");
return new RxJavaCallAdapterFactory(scheduler, false);
}
private RxJavaCallAdapterFactory(Scheduler scheduler, boolean isAsync) {
//主要的是這個Scheduler 用于RxJava中的調(diào)度器
this.scheduler = scheduler;
this.isAsync = isAsync;
}
由此我們可以看出來addConverterFactory()和addCallAdapterFactory()方法很類似,就是創(chuàng)建默認(rèn)的(我們想要使用的數(shù)據(jù)轉(zhuǎn)換器和網(wǎng)絡(luò)適配器),并對 converterFactories 、adapterFactories這兩個進(jìn)行添加數(shù)據(jù)
build()方法
public Retrofit build() {
//首先判斷baseUrl 這個不能為空
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//這個網(wǎng)絡(luò)請求執(zhí)行器 用于產(chǎn)生call 代表實(shí)際的http請求
okhttp3.Call.Factory callFactory = this.callFactory;
//如果為空 就會創(chuàng)建一個OkHttpClient 這里也就是說retrofit默認(rèn)就是Okhttp作為底層網(wǎng)絡(luò)請求
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//初始化回調(diào)方法的執(zhí)行器 用在retrofit異步請求的時候(同步請求是不需要的) 子線程耗時操作-->UI線程更新UI
Executor callbackExecutor = this.callbackExecutor;
//如果為空的是 就會創(chuàng)建一個默認(rèn)的回調(diào)執(zhí)行器 這個默認(rèn)的是在platform里面的默認(rèn)創(chuàng)建方法 也就是主線程的那個
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
//網(wǎng)絡(luò)請求適配器集合 將成員變量當(dāng)中的網(wǎng)絡(luò)請求適配器工廠作為參數(shù)傳到arraylist的構(gòu)造函數(shù)當(dāng)中 主要用于配置網(wǎng)絡(luò)請求適配器的工廠
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
//創(chuàng)建好網(wǎng)絡(luò)請求適配器工廠之后 添加我們這個安卓平臺的默認(rèn)的網(wǎng)絡(luò)請求適配器
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
//
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
//這個時候傳入到Retrofit的構(gòu)造方法中 創(chuàng)建Retrofit對象
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
這個時候我們簡單的過了創(chuàng)建Retrofit實(shí)例的過程,可以通過建造者模式來對相應(yīng)的數(shù)值進(jìn)行初始化,配置相關(guān)的數(shù)據(jù)轉(zhuǎn)換器和適配器,最后通過build方法完成創(chuàng)建Retrofit的實(shí)例。