在項(xiàng)目開發(fā)中其實(shí)最常見的網(wǎng)絡(luò)請(qǐng)求框架就是OkHttp+Retrofit铃岔,在上一篇老生新談牲距,從OkHttp原理看網(wǎng)絡(luò)請(qǐng)求剖析了OkHttp的原理,今天這篇文章將從不同的角度來看Retrofit的內(nèi)部實(shí)現(xiàn)逢净。
讀完這篇文章,您將了解到:
- 什么是動(dòng)態(tài)代理模式歼指?
- Retrofit為什么要使用動(dòng)態(tài)代理爹土?
- Retrofit如何與OkHttp相結(jié)合?
- Retrofit是如何將子線程切換到主線程踩身?
- Retrofit彌補(bǔ)了OkHttp的哪些缺點(diǎn)胀茵?
以下源碼版本為retrofit:2.9.0
什么是動(dòng)態(tài)代理?
在Retrofit源碼分析之前需要了解的一個(gè)比較重要的點(diǎn)挟阻,就是動(dòng)態(tài)代理模式琼娘,它是Retrofit的核心設(shè)計(jì)的開始。
動(dòng)態(tài)代理和靜態(tài)代理都屬于代理模式附鸽,動(dòng)態(tài)代理是可以在運(yùn)行期動(dòng)態(tài)創(chuàng)建某個(gè)interface的實(shí)例脱拼,我們通過Proxy.newProxyInstance
產(chǎn)生的代理類,當(dāng)調(diào)用接口的任何方法時(shí)坷备,都會(huì)被InvocationHandler#invoke
方法攔截熄浓,同時(shí),在這個(gè)方法中可以拿到所傳入的參數(shù)等省撑,依照參數(shù)值再做相應(yīng)的處理赌蔑。
定義比較抽象,舉個(gè)普通的例子竟秫。
例如某用戶近期需要購房娃惯,那么他就需要委托中介幫忙推薦房源,之后買家通過中介與開發(fā)商達(dá)成買賣協(xié)議肥败。這里的中介就是代理對(duì)象趾浅,買家則是委托者,而其中“推薦房源”這件事情拙吉,則是抽象對(duì)象潮孽,也是委托者真正需要做的動(dòng)作。
看下偽代碼筷黔,首先定義委托者想要做的動(dòng)作往史,并且告訴中介我對(duì)房子的一些基本要求:
/**
* 買家委托中介購房。
*/
interface ToDo {
fun buyHouse()
}
定義代理對(duì)象佛舱,即中介椎例,并實(shí)現(xiàn)InvocationHandler挨决,根據(jù)委托者的要求點(diǎn)返回代理對(duì)象:
/**
* 中介
*/
class Middlemen(private val any: Any) : InvocationHandler {
override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any? {
return method?.invoke(any, *(args ?: arrayOfNulls<Any>(0)))
}
}
委托者告訴中介,我要購房的信息:
/**
* 買家
*/
class Buyer : ToDo {
override fun buyHouse() {
print("中介订歪,請(qǐng)幫我買房子")
}
}
最后利用代理對(duì)象實(shí)現(xiàn)購房的動(dòng)作:
fun main(args: Array<String>) {
val toDo: ToDo = Buyer()
val dynamicMid = Proxy.newProxyInstance(
toDo.javaClass.classLoader, toDo.javaClass.interfaces,
Middlemen(toDo)
) as ToDo
dynamicMid.buyHouse()
}
動(dòng)態(tài)代理最主要的部分在于代理對(duì)象實(shí)現(xiàn)InvocationHandler脖祈,并重寫invoke方法。 當(dāng)代理對(duì)象代理了委托者的要求刷晋,不管要求有多少盖高,當(dāng)代理執(zhí)行時(shí),都會(huì)走進(jìn)invoke()方法中眼虱。這是重點(diǎn)喻奥,圈起來后面要考。
我們應(yīng)該了解到捏悬,Retrofit的核心部分就在這動(dòng)態(tài)代理中撞蚕,那Retrofit為什么要使用動(dòng)態(tài)代理?且動(dòng)態(tài)代理中又做了哪些動(dòng)作过牙? ??
那就接著往下分析源碼甥厦。
源碼解析
在源碼分析之前,有兩個(gè)重要的對(duì)象需要提前說明寇钉,提前了解他們的作用刀疙,更有利于后續(xù)的源碼解讀。
一個(gè)是CallAdapter扫倡,另外則是Converter庙洼。
- CallAdapter: 適配器,我們默認(rèn)定義API Service方法的返回值為Call<T>類型镊辕,但是有時(shí)候會(huì)自定義返回類型油够,例如和RxJava相結(jié)合,返回Observable或者Single類型的時(shí)候應(yīng)該怎么處理征懈?CallAdapter的作用就是幫助開發(fā)者去適配這些返回類型石咬,你定義了什么類型的數(shù)據(jù),就可以通過CallAdapter#adapt進(jìn)行返回卖哎。
- Converter: 數(shù)據(jù)裝換器鬼悠,主要負(fù)責(zé)把服務(wù)器返回的數(shù)據(jù)ResponseBody轉(zhuǎn)化為 T 類型的對(duì)象。例如在使用retrofit進(jìn)行網(wǎng)絡(luò)請(qǐng)求時(shí)亏娜,我們都會(huì)先定義一個(gè)返回值的實(shí)體類焕窝,Converter就會(huì)將網(wǎng)絡(luò)請(qǐng)求的返回值轉(zhuǎn)換為我們所需要的類型。
CallAdapter和Converter的作用如上述所說维贺,接下來就直接進(jìn)入到retrofit的動(dòng)態(tài)代理源碼中它掂。
public <T> T create(final Class<T> service) {
validateServiceInterface(service);
return (T)
Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] {service},
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override
public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
1??
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
args = args != null ? args : emptyArgs;
2??
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
retrofit的創(chuàng)建在于retrofit.create(ApiService::class.java)
,內(nèi)部使用動(dòng)態(tài)代理模式,可以看到invoke方法中一開始就有幾個(gè)判斷:
- 1??判斷當(dāng)前方法是否是在接口中聲明虐秋,如果不是則直接按照正常流程調(diào)用invoke榕茧;
- 2??判斷是否屬于Android平臺(tái)的默認(rèn)方法,如果是則直接按照正常流程調(diào)用invoke客给,反之用押,則就到了動(dòng)態(tài)代理的核心部分:
loadServiceMethod(method).invoke(args)
。
最后一行代碼主要分為兩步:loadServiceMethod(method)
和invoke(args)
:
loadServiceMethod(method)
這個(gè)方法的作用先提一下靶剑,它主要是將網(wǎng)絡(luò)請(qǐng)求方法中的信息進(jìn)行初步的處理蜻拨,我們?cè)趧?chuàng)建api service具體接口時(shí),會(huì)加上注解(@GET桩引,@POST官觅,@PUT...),參數(shù)(@Path阐污、@Query...)等,該方法就是對(duì)接口中的注解咱圆、參數(shù)等進(jìn)行解析笛辟,解析接口后又生成了一個(gè)RequestFactory請(qǐng)求工廠對(duì)象,并且利用這個(gè)RequestFactory對(duì)象創(chuàng)建了一個(gè)CallAdapter序苏。
invoke(args)
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
invoke的實(shí)現(xiàn)中也只有兩行代碼手幢。
第一行:主要利用loadServiceMethod所創(chuàng)建的RequestFactory以及一些轉(zhuǎn)換類作為參數(shù)生成一個(gè)OkHttpCall對(duì)象, OkHttpCall其實(shí)是對(duì)OkHttp中的realCall進(jìn)行了一層包裝(realCall可參考上一篇OkHttp的解析)忱详,
在Retrofit里围来,OkHttpCall緊密連接OkHttp,它的內(nèi)部同樣可以調(diào)用同步execute匈睁、 異步execute方法進(jìn)行網(wǎng)絡(luò)請(qǐng)求监透,其實(shí)真正調(diào)用的也就是OkHttp的execute和execute方法。在此同時(shí)航唆,Retrofit中會(huì)對(duì)請(qǐng)求響應(yīng)也做了解析胀蛮。
我們先來看看OkHttpCall中網(wǎng)絡(luò)請(qǐng)求的細(xì)節(jié):
@Override
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
okhttp3.Call call;
synchronized (this) {
...
if (call == null && failure == null) {
try {
call = rawCall = createRawCall();
}
}
...
call.enqueue(
new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
//解析請(qǐng)求返回值
response = parseResponse(rawResponse);
}
...
try {
callback.onResponse(OkHttpCall.this, response);
}
@Override
public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
}
}
});
}
以一個(gè)異步請(qǐng)求為例,
內(nèi)部首先調(diào)用了一個(gè)createRawCall()方法糯钙,創(chuàng)建rawCall粪狼,這個(gè)rawCall其實(shí)指代的就是Okhttp3的call,也就是OkHttp進(jìn)行網(wǎng)絡(luò)請(qǐng)求調(diào)用的一個(gè)調(diào)度器任岸;
創(chuàng)建好OkHttp的call后再榄,就開始調(diào)用enqueue進(jìn)行異步請(qǐng)求,發(fā)現(xiàn)在異步請(qǐng)求內(nèi)響應(yīng)的回調(diào)屬于okhttp3.Callback享潜,所返回來的結(jié)果困鸥,也都是okhttp3.Response,到這里就可以大概知道了剑按,retrofit的網(wǎng)絡(luò)請(qǐng)求其實(shí)還是由OkHttp來實(shí)現(xiàn)窝革。
okhttp3.Response這個(gè)響應(yīng)不方便開發(fā)者直接使用购城,所以retrofit在收到結(jié)果后,又對(duì)響應(yīng)結(jié)果進(jìn)行新一輪的解析
response = parseResponse(rawResponse)
虐译,以Response對(duì)象的形式返回給開發(fā)者瘪板。
另外還有最后一行: adapt(call, args); 它的內(nèi)部其實(shí)是由一個(gè)適配器CallAdapted
來調(diào)用,如下:
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call);
}
在源碼解析的一開始就對(duì)callAdapter進(jìn)行了定義漆诽,這里將詳細(xì)說明侮攀。
adapt是一個(gè)抽象方法,里面?zhèn)魅肓松厦鎰倓?chuàng)建的OkHttpCall作為參數(shù)厢拭。adapt即adapter兰英,適配器的意思,那我們可以猜測(cè)一下供鸠,傳入OkHttpCall畦贸,是不是就是為了對(duì)OkHttpCall再進(jìn)行適配的工作?但楞捂,OkHttpCall已經(jīng)可以進(jìn)行網(wǎng)絡(luò)請(qǐng)求了薄坏,為什么還需要使用CallAdapted進(jìn)行再次的適配呢? ??這個(gè)問題還是先記下寨闹,拋到后面解答胶坠。
咱們繼續(xù)來分析動(dòng)態(tài)代理的主線條,從上面分析知道繁堡,retrofit之所以調(diào)用簡(jiǎn)便沈善,是因?yàn)閮?nèi)部對(duì)@GET,@POST椭蹄,@Path等注解以及請(qǐng)求參數(shù)進(jìn)行了解析闻牡,讓開發(fā)者只需要關(guān)心自己新增的請(qǐng)求方法是不是符合規(guī)范。
而上述動(dòng)態(tài)代理最主要做的事情就是創(chuàng)建了CallAdapted绳矩,CallAdapted其實(shí)只是一個(gè)適配器澈侠,主要需要了解的是它適配的是什么? 是否還記得我們?cè)谏厦鎾伋隽艘粋€(gè)關(guān)于CallAdapted的問題:那就先來看看他是如何創(chuàng)建的埋酬???
CallAdapted
loadServiceMethod方法其實(shí)返回的就是CallAdapted對(duì)象哨啃,那我們就直奔主題,進(jìn)去瞧一瞧写妥,
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
Type adapterType;
if (isKotlinSuspendFunction) {
Type[] parameterTypes = method.getGenericParameterTypes();
Type responseType =
Utils.getParameterLowerBound(
0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
// Unwrap the actual body type from Response<T>.
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
continuationWantsResponse = true;
}
adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
} else {
adapterType = method.getGenericReturnType();
}
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
...
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
跟蹤到最后拳球,是在HttpServiceMethod類中的parseAnnotations中發(fā)現(xiàn)了CallAdapted的創(chuàng)建..
public CallAdapter<?, ?> nextCallAdapter(
@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
CallAdapter是根據(jù)returnType和annotations的類型,從callAdapterFactories工廠中進(jìn)行查找珍特,從而返回所對(duì)應(yīng)的網(wǎng)絡(luò)請(qǐng)求適配器祝峻,這里returnType指的是網(wǎng)絡(luò)請(qǐng)求接口里方法的返回值類型,如Call<?>、Observable<?>等莱找。annotations則指代的是注解類型酬姆,如@GET、@POST等奥溺。
這里也提到了一個(gè)適配器工廠callAdapterFactories辞色,不同的CallAdapter就是從這個(gè)工廠中查詢出來的,有查找那就必定有添加浮定,那適配器CallAdapter是怎么添加到工廠類中的相满? ??callAdapterFactories這個(gè)變量是屬于Retrofit類,跟蹤發(fā)現(xiàn)是由Retrofit構(gòu)造函數(shù)傳入桦卒,也就是Retrofit初始化時(shí)進(jìn)行了賦值立美。
Retrofit的初始化是由一種建造者模式來創(chuàng)建,在Retrofit的build()方法中方灾,找到了適配器工廠對(duì)其適配器的添加:
public Retrofit build() {
...
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
//添加適配器callAdapter
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
...
return new Retrofit(
callFactory,
baseUrl,
unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories),
callbackExecutor,
validateEagerly);
}
platform.defaultCallAdapterFactories
指的是Android平臺(tái)的一個(gè)默認(rèn)的適配器工廠建蹄,當(dāng)我們不使用自定義適配器工廠時(shí),則添加的就是這默認(rèn)的工廠裕偿。這里提到了自定義適配器工廠洞慎,其實(shí)我們?cè)谑褂肦etrofit的時(shí)候,有時(shí)候會(huì)和RxJava結(jié)合击费,例如在創(chuàng)建Retrofit時(shí),也會(huì)addCallAdapterFactory桦他,將RxJava2CallAdapterFactory添加到callAdapterFactories中蔫巩。
mRetrofit = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl(baseUrl)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
添加調(diào)用適配器工廠的目的就是支持Call以外的服務(wù)方法返回類型,如支持Observable快压,Single返回類型等圆仔。 在callAdapterFactories集合器添加一個(gè)默認(rèn)適配器工廠時(shí),也附帶傳進(jìn)去了一個(gè)參數(shù)callbackExecutor蔫劣,callbackExecutor是Java8或者Android平臺(tái)的一個(gè)默認(rèn)線程調(diào)度器坪郭,它的作用涉及到一個(gè)線程切換的問題,也就是后續(xù)需要分析的retrofit是如何將子線程切換到主線程脉幢???
這個(gè)問題還是先記下歪沃,后面針對(duì)線程切換詳細(xì)說明。
在上面源碼創(chuàng)建CallAdapter時(shí)嫌松,有一個(gè)對(duì)象也同時(shí)被創(chuàng)建沪曙,那就是Converter。
Converter
Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType);
Converter在文章一開頭也說過萎羔,是數(shù)據(jù)裝換器液走。它的添加和獲取方式和CallAdapter類似。在Retrofit初始化時(shí)添加到List<Converter.Factory>工廠集合,例如與GSon結(jié)合時(shí)缘眶,addConverterFactory(GsonConverterFactory.create()
mRetrofit = new Retrofit.Builder()
.client(mOkHttpClient)
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create()
.build();
后面也根據(jù)類型Type取出不同的Converter嘱根,對(duì)返回的網(wǎng)絡(luò)響應(yīng),做出數(shù)據(jù)的轉(zhuǎn)換巷懈,例如轉(zhuǎn)換成實(shí)體類该抒。
基本邏輯與CallAdapter類似。
說了這么多砸喻,是不是有點(diǎn)思路了柔逼,我們先來捋一捋。
- 一開始動(dòng)態(tài)代理中調(diào)用loadServiceMethod方法割岛,解析接口方法中的注解愉适,參數(shù),頭部信息等癣漆;
- 依據(jù)接口方法的返回類型维咸,從適配器工廠集合里進(jìn)行查詢,生成相應(yīng)的適配器CallAdapter惠爽,區(qū)分是RxJava的Observable癌蓖、Single還是Call或者其他類型,(適配器工廠集合的數(shù)據(jù)是由構(gòu)建Retrofit時(shí)addCallAdapterFactory()添加婚肆,如無自定義租副,則添加Android平臺(tái)默認(rèn)適配器)。以相同的方式取出數(shù)據(jù)轉(zhuǎn)換器Converter较性;
- 利用上面生成的CallAdapter用僧,調(diào)用invoke方法,創(chuàng)建OkHttpCall對(duì)象赞咙,即針對(duì)請(qǐng)求信息责循,利用OkHttp進(jìn)行異步或者同步網(wǎng)絡(luò)請(qǐng)求,并且對(duì)響應(yīng)結(jié)果進(jìn)行實(shí)體類轉(zhuǎn)換攀操;
- 創(chuàng)建好OkHttpCall后院仿,又利用上面查詢到的適配器CallAdapter調(diào)用adapt,返回RxJava的Observable速和、Single或者Call對(duì)象歹垫。
在Retrofit初始化時(shí)有涉及到一個(gè)參數(shù)callbackExecutor,當(dāng)時(shí)拋出了一個(gè)問題:Retrofit是如何將子線程切換到主線程颠放?這里就來詳細(xì)看看县钥。
Retrofit是如何將子線程切換到主線程?
在添加默認(rèn)適配器工廠defaultCallAdapterFactories時(shí)慈迈,將callbackExecutor作為了一個(gè)參數(shù)若贮,那么它的具體實(shí)現(xiàn)也就是在這個(gè)默認(rèn)適配器工廠中省有。
我們來看下callbackExecutor在里面做了些啥。
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
...
@Override
public void enqueue(final Callback<T> callback) {
delegate.enqueue(
new Callback<T>() {
@Override
public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(
() -> {
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(() -> callback.onFailure(ExecutorCallbackCall.this, t));
}
});
}
在上述代碼里了解到谴麦,callbackExecutor即Executor蠢沿,一個(gè)線程調(diào)度器。在Call的enqueue實(shí)現(xiàn)里執(zhí)行了一個(gè)異步網(wǎng)絡(luò)請(qǐng)求delegate.enqueue匾效,在請(qǐng)求的響應(yīng)onResponse舷蟀、onFailure中
Executor也同樣執(zhí)行了一個(gè)線程,這里就有個(gè)疑問面哼,為什么要在一個(gè)異步請(qǐng)求里又調(diào)用一個(gè)線程野宜?我們知道callbackExecutor是一個(gè)線程調(diào)度器,那他內(nèi)部到底實(shí)現(xiàn)的是什么魔策?
默認(rèn)callbackExecutor的創(chuàng)建在Retrofit的初始化中匈子,callbackExecutor = platform.defaultCallbackExecutor();
static final class Android extends Platform {
@Override
public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
static final class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
handler.post(r);
}
}
}
}
platform是一個(gè)Android平臺(tái),defaultCallbackExecutor
內(nèi)部其實(shí)調(diào)用的是 new MainThreadExecutor()
闯袒,很清楚的看到虎敦, handler.post(r)
內(nèi)部使用Handler將響應(yīng)拋到了主線程。
這就是Retrofit將子線程切換到主線程的核心所在政敢。
Retrofit為什么要使用動(dòng)態(tài)代理其徙?
文章一開始就拋出了這個(gè)問題,經(jīng)過一輪分析后喷户,也就有了答案唾那。
我們想一下,動(dòng)態(tài)代理的優(yōu)勢(shì)是什么褪尝?是不是不用暴露真實(shí)的委托者闹获,根據(jù)不同的委托創(chuàng)建不同的代理,通過代理去做事情恼五。
那Retrofit彌補(bǔ)了OkHttp的缺點(diǎn)又指的是什么昌罩?OkHttp在使用的時(shí)候哭懈,請(qǐng)求參數(shù)的配置是不是很繁瑣灾馒,尤其當(dāng)有一些表單提交時(shí),又臭又長(zhǎng)遣总,而Retrofit就是彌補(bǔ)了這個(gè)缺點(diǎn)睬罗,利用@GET、@POST旭斥、@Path容达、@Body等注解以及一些參數(shù)很簡(jiǎn)便的就構(gòu)造出了請(qǐng)求。
當(dāng)Retrofit創(chuàng)建了不同的接口垂券,動(dòng)態(tài)代理就發(fā)揮出了作用花盐。每當(dāng)不同接口方法執(zhí)行時(shí)羡滑,動(dòng)態(tài)代理都會(huì)攔截該請(qǐng)求,對(duì)接口中的注解算芯,參數(shù)進(jìn)行解析柒昏,構(gòu)建出不同的Request,最后則交給OkHttp去真正執(zhí)行熙揍。
Retrofit結(jié)合動(dòng)態(tài)代理职祷,不用關(guān)心真正的接口方法,對(duì)符合規(guī)范的接口進(jìn)行統(tǒng)一化的管理届囚,以統(tǒng)一的方式解析注解和參數(shù)有梆,拼接成request。
總結(jié)
通過源碼以及問題的解答意系,了解到Retrofit其實(shí)是OkHttp的封裝類泥耀,內(nèi)部網(wǎng)絡(luò)請(qǐng)求還是靠的OkHttp,那Retrofit封裝后改變了什么昔字?
- 接口請(qǐng)求更加簡(jiǎn)便爆袍,標(biāo)注注解@GET、@POST作郭、@Path陨囊、@Body等就形成一個(gè)網(wǎng)絡(luò)請(qǐng)求;
- 默認(rèn)幫助開發(fā)者解析responseBody夹攒,另外還可以自定義解析策略蜘醋;
- Retrofit幫助開發(fā)者進(jìn)行線程切換;
- Retrofit帶給開發(fā)者更多的權(quán)限咏尝,可自定義適配網(wǎng)絡(luò)請(qǐng)求压语。
Retrofit源碼不多,但是卻包含了很多設(shè)計(jì)技巧编检,后續(xù)將開一篇詳細(xì)說明Retrofit的設(shè)計(jì)之美胎食。
以上便是Retrofit的源碼解析,希望這篇文章能幫到您允懂,感謝閱讀厕怜。
推薦閱讀
老生新談,從OkHttp原理看網(wǎng)絡(luò)請(qǐng)求
【網(wǎng)絡(luò)篇】開發(fā)必備知識(shí)點(diǎn):UDP/TCP協(xié)議
歡迎關(guān)注公 z 號(hào):9點(diǎn)大前端蕾总,每天9點(diǎn)推薦更多前端粥航、Android、Flutter文章