總體概括:
1.App應(yīng)用程序通過 Retrofit 請(qǐng)求網(wǎng)絡(luò)心赶,實(shí)際上是使用 Retrofit 接口層封裝請(qǐng)求參數(shù)、Header缺猛、Url 等信息缨叫,之后由 OkHttp 完成后續(xù)的請(qǐng)求操作
2.在服務(wù)端返回?cái)?shù)據(jù)之后,OkHttp 將原始的結(jié)果交給 Retrofit荔燎,Retrofit根據(jù)用戶的需求對(duì)結(jié)果進(jìn)行解析
<-- 步驟1:創(chuàng)建Retrofit 類實(shí)例 -->
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://fanyi.youdao.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
Retrofit實(shí)例是使用建造者模式通過Builder類進(jìn)行創(chuàng)建的(
建造者模式:將一個(gè)復(fù)雜對(duì)象的構(gòu)建與表示分離耻姥,使得用戶在不知道對(duì)象的創(chuàng)建細(xì)節(jié)情況下就可以直接創(chuàng)建復(fù)雜的對(duì)象)
① new Retrofit:
serviceMethod:包含所有網(wǎng)絡(luò)請(qǐng)求信息的對(duì)象
baseUrl:網(wǎng)絡(luò)請(qǐng)求的url地址
callFactory:網(wǎng)絡(luò)請(qǐng)求工廠
adapterFactories:網(wǎng)絡(luò)請(qǐng)求適配器工廠的集合(生產(chǎn)網(wǎng)絡(luò)請(qǐng)求適配器(CallAdapter))
converterFactories:數(shù)據(jù)轉(zhuǎn)換器工廠的集合
callbackExecutor:回調(diào)方法執(zhí)行器
② .Builder()
平臺(tái)類型對(duì)象:Android
網(wǎng)絡(luò)請(qǐng)求適配器工廠:CallAdapterFactory(CallAdapter用于對(duì)原始Call進(jìn)行再次封裝,如Call<R>到Observable<R>)
數(shù)據(jù)轉(zhuǎn)換器工廠: converterFactory
回調(diào)執(zhí)行器:callbackExecutor
③ .baseUrl("http://fanyi.youdao.com/")
baseUrl()用于配置Retrofit類的網(wǎng)絡(luò)請(qǐng)求url地址
④.addConverterFactory(GsonConverterFactory.create())
步驟4用于創(chuàng)建一個(gè)含有Gson對(duì)象實(shí)例的GsonConverterFactory并放入到數(shù)據(jù)轉(zhuǎn)換器工廠converterFactories里
⑤ .build();
在最后一步中有咨,通過前面步驟設(shè)置的變量琐簇,將Retrofit類的所有成員變量都配置完畢。
<-- 步驟3:在MainActivity創(chuàng)建接口類實(shí)例 -->
AccessApi NetService = retrofit.create(NetService.class);
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override
public Object invoke(Object proxy, Method method, Object... args)
throws Throwable {
// 關(guān)注點(diǎn)1
// 作用:讀取網(wǎng)絡(luò)請(qǐng)求接口里的方法座享,并根據(jù)前面配置好的屬性配置serviceMethod對(duì)象
ServiceMethod serviceMethod = loadServiceMethod(method);
// 關(guān)注點(diǎn)2
// 作用:根據(jù)配置好的serviceMethod對(duì)象創(chuàng)建okHttpCall對(duì)象
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
// 關(guān)注點(diǎn)3
// 作用:調(diào)用OkHttp婉商,并根據(jù)okHttpCall返回rejava的Observe對(duì)象或者返回Call,通過serviceMethod.callAdapter.adapt()方法渣叛,將OkHttpCall進(jìn)行代理包裝
return serviceMethod.callAdapter.adapt(okHttpCall);
}
<-- 步驟4:對(duì)發(fā)送請(qǐng)求的url進(jìn)行封裝丈秩,即生成最終的網(wǎng)絡(luò)請(qǐng)求對(duì)象 -->
Call<JavaBean> call = NetService.getCall();
NetService對(duì)象實(shí)際上是動(dòng)態(tài)代理對(duì)象Proxy.newProxyInstance()(步驟3中已說明),并不是真正的網(wǎng)絡(luò)請(qǐng)求接口創(chuàng)建的對(duì)象
當(dāng)NetService對(duì)象調(diào)用getCall()時(shí)會(huì)被動(dòng)態(tài)代理對(duì)象Proxy.newProxyInstance()攔截淳衙,然后調(diào)用自身的InvocationHandler # invoke()
invoke(Object proxy, Method method, Object... args)會(huì)傳入3個(gè)參數(shù):Object proxy:(代理對(duì)象)蘑秽、
Method method(調(diào)用的getCall())
Object... args(方法的參數(shù),即getCall()中的)
接下來利用Java反射獲取到getCall()的注解信息箫攀,配合args參數(shù)創(chuàng)建ServiceMethod對(duì)象肠牲。
步驟3,4總結(jié):
動(dòng)態(tài)創(chuàng)建網(wǎng)絡(luò)請(qǐng)求接口的實(shí)例(代理模式 - 動(dòng)態(tài)代理)
創(chuàng)建 serviceMethod 對(duì)象(建造者模式 & 單例模式(緩存機(jī)制))
對(duì) serviceMethod 對(duì)象進(jìn)行網(wǎng)絡(luò)請(qǐng)求參數(shù)配置:通過解析網(wǎng)絡(luò)請(qǐng)求接口方法的參數(shù)、返回值和注解類型靴跛,從Retrofit對(duì)象中獲取對(duì)應(yīng)的網(wǎng)絡(luò)請(qǐng)求的url地址缀雳、網(wǎng)絡(luò)請(qǐng)求執(zhí)行器、網(wǎng)絡(luò)請(qǐng)求適配器 & 數(shù)據(jù)轉(zhuǎn)換器汤求。(策略模式)
對(duì) serviceMethod 對(duì)象加入線程切換的操作俏险,便于接收數(shù)據(jù)后通過Handler從子線程切換到主線程從而對(duì)返回?cái)?shù)據(jù)結(jié)果進(jìn)行處理(裝飾模式)
最終創(chuàng)建并返回一個(gè)OkHttpCall類型的網(wǎng)絡(luò)請(qǐng)求對(duì)象
首先構(gòu)造retrofit,幾個(gè)核心的參數(shù)呢扬绪,主要就是baseurl,callFactory(默認(rèn)okhttpclient),converterFactories,adapterFactories,excallbackExecutor竖独。
然后通過create方法拿到接口的實(shí)現(xiàn)類,這里利用Java的Proxy類完成動(dòng)態(tài)代理的相關(guān)代理
在invoke方法內(nèi)部挤牛,拿到我們所聲明的注解以及實(shí)參等莹痢,構(gòu)造ServiceMethod,ServiceMethod中解析了大量的信息,最痛可以通過toRequest構(gòu)造出okhttp3.Request對(duì)象竞膳。有了okhttp3.Request對(duì)象就可以很自然的構(gòu)建出okhttp3.call航瞭,最后calladapter對(duì)Call進(jìn)行裝飾返回。
拿到Call就可以執(zhí)行enqueue或者execute方法了
只要知道ServiceMethod主要用于將我們接口中的方法轉(zhuǎn)化為一個(gè)Request對(duì)象坦辟,于是根據(jù)我們的接口返回值確定了responseConverter,解析我們方法上的注解拿到初步的url,解析我們參數(shù)上的注解拿到構(gòu)建RequestBody所需的各種信息刊侯,最終調(diào)用toRequest的方法完成Request的構(gòu)建。