AndroidRetrofit原理深入探索_第1頁
AndroidRetrofit原理深入探索_第2頁
AndroidRetrofit原理深入探索_第3頁
AndroidRetrofit原理深入探索_第4頁
AndroidRetrofit原理深入探索_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第AndroidRetrofit原理深入探索目錄序章Retrofit構(gòu)建過程創(chuàng)建網(wǎng)絡(luò)請求接口實例過程執(zhí)行請求過程總結(jié)

序章

首先引入依賴

implementationcom.squareup.retrofit2:retrofit:2.9.0

在原理之前,我們先來回憶一下Retrofit的基本使用

1、定義接口

interfaceMyService{

@GET("gallery/{imageType}/response")

fungetImages(@Path("imageType")imageType:String):CallListString

2、構(gòu)建Retrofit,創(chuàng)建網(wǎng)絡(luò)請求接口類實例

valretrofit=Retrofit.Builder()

.baseUrl(BASE_URL)

.build()

valmyService=retrofit.create(MyService::class.java)

3、生成Call,執(zhí)行請求

valresp=myService.getImages("banner")

resp.enqueue(object:CallbackListString{

overridefunonResponse(call:CallListString,response:ResponseListString){

TODO("Notyetimplemented")

overridefunonFailure(call:CallListString,t:Throwable){

TODO("Notyetimplemented")

})

這樣一個基本的網(wǎng)絡(luò)請求就搞定了,使用很簡潔,正是因為其內(nèi)部使用了大量的設(shè)計模式和優(yōu)秀的架構(gòu)設(shè)計,才得以使其如此方便地進行網(wǎng)絡(luò)請求,下面我們就一起來探索探索Retrofit的設(shè)計之美。

Retrofit構(gòu)建過程

使用了建造者模式通過內(nèi)部靜態(tài)類Builder構(gòu)建一個Retrofit實例,這里只列出了部分方法,其他類似

publicstaticfinalclassBuilder{

privatefinalPlatformplatform;

//網(wǎng)絡(luò)請求工廠,工廠方法模式

private@Nullableokhttp3.Call.FactorycallFactory;

//網(wǎng)絡(luò)請求地址

private@NullableHttpUrlbaseUrl;

//數(shù)據(jù)轉(zhuǎn)換器工廠的集合

privatefinalListConverter.FactoryconverterFactories=newArrayList();

//網(wǎng)絡(luò)請求適配器工廠的集合,默認是ExecutorCallAdapterFactory

privatefinalListCallAdapter.FactorycallAdapterFactories=newArrayList();

//回調(diào)方法執(zhí)行器,用于切換線程

private@NullableExecutorcallbackExecutor;

//一個開關(guān),為true則會緩存創(chuàng)建的ServiceMethod

privatebooleanvalidateEagerly;

//......

publicBuilderbaseUrl(StringbaseUrl){

Objects.requireNonNull(baseUrl,"baseUrl==null");

returnbaseUrl(HttpUrl.get(baseUrl));

publicBuilderbaseUrl(HttpUrlbaseUrl){

Objects.requireNonNull(baseUrl,"baseUrl==null");

ListStringpathSegments=baseUrl.pathSegments();

if(!"".equals(pathSegments.get(pathSegments.size()-1))){

thrownewIllegalArgumentException("baseUrlmustendin/:"+baseUrl);

this.baseUrl=baseUrl;

returnthis;

//將一個含有Gson對象實例的GsonConverterFactory放入數(shù)據(jù)轉(zhuǎn)換器工廠

publicBuilderaddConverterFactory(Converter.Factoryfactory){

converterFactories.add(Objects.requireNonNull(factory,"factory==null"));

returnthis;

//......

}

通過build,我們上面Builder類中的參數(shù)對象都配置到了Retrofit對象中。

publicRetrofitbuild(){

if(baseUrl==null){

thrownewIllegalStateException("BaseURLrequired.");

okhttp3.Call.FactorycallFactory=this.callFactory;

if(callFactory==null){

callFactory=newOkHttpClient();

ExecutorcallbackExecutor=this.callbackExecutor;

if(callbackExecutor==null){

callbackExecutor=platform.defaultCallbackExecutor();

//MakeadefensivecopyoftheadaptersandaddthedefaultCalladapter.

ListCallAdapter.FactorycallAdapterFactories=newArrayList(this.callAdapterFactories);

callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

//Makeadefensivecopyoftheconverters.

ListConverter.FactoryconverterFactories=

newArrayList(

1+this.converterFactories.size()+platform.defaultConverterFactoriesSize());

//Addthebuilt-inconverterfactoryfirst.Thispreventsoverridingitsbehaviorbutalso

//ensurescorrectbehaviorwhenusingconvertersthatconsumealltypes.

converterFactories.add(newBuiltInConverters());

converterFactories.addAll(this.converterFactories);

converterFactories.addAll(platform.defaultConverterFactories());

returnnewRetrofit(

callFactory,

baseUrl,

unmodifiableList(converterFactories),

unmodifiableList(callAdapterFactories),

callbackExecutor,

validateEagerly);

}

創(chuàng)建網(wǎng)絡(luò)請求接口實例過程

使用動態(tài)代理的方式拿到所有注解配置后,創(chuàng)建網(wǎng)絡(luò)請求接口實例。

publicTTcreate(finalClassTservice){

validateServiceInterface(service);

return(T)

Proxy.newProxyInstance(

service.getClassLoader(),

newClass[]{service},

newInvocationHandler(){

privatefinalPlatformplatform=Platform.get();

privatefinalObject[]emptyArgs=newObject[0];

@Override

public@NullableObjectinvoke(Objectproxy,Methodmethod,@NullableObject[]args)

throwsThrowable{

//IfthemethodisamethodfromObjectthendefertonormalinvocation.

if(method.getDeclaringClass()==Object.class){

returnmethod.invoke(this,args);

args=args!=nullargs:emptyArgs;

returnplatform.isDefaultMethod(method)

platform.invokeDefaultMethod(method,service,proxy,args)

:loadServiceMethod(method).invoke(args);

}

跟蹤loadServiceMethod,parseAnnotations解析注解配置得到ServiceMethod,然后加入到serviceMethodCache緩存中,是一個ConcurrentHashMap。

ServiceMethodloadServiceMethod(Methodmethod){

ServiceMethodresult=serviceMethodCache.get(method);

if(result!=null)returnresult;

synchronized(serviceMethodCache){

result=serviceMethodCache.get(method);

if(result==null){

result=ServiceMethod.parseAnnotations(this,method);

serviceMethodCache.put(method,result);

returnresult;

}

abstractclassServiceMethodT{

staticTServiceMethodTparseAnnotations(Retrofitretrofit,Methodmethod){

RequestFactoryrequestFactory=RequestFactory.parseAnnotations(retrofit,method);

TypereturnType=method.getGenericReturnType();

if(Utils.hasUnresolvableType(returnType)){

throwmethodError(

method,

"Methodreturntypemustnotincludeatypevariableorwildcard:%s",

returnType);

if(returnType==void.class){

throwmethodError(method,"Servicemethodscannotreturnvoid.");

returnHttpServiceMethod.parseAnnotations(retrofit,method,requestFactory);

abstract@NullableTinvoke(Object[]args);

}

執(zhí)行請求過程

publicvoidenqueue(finalCallbackTcallback){

Objects.requireNonNull(callback,"callback==null");

okhttp3.Callcall;

Throwablefailure;

synchronized(this){

if(executed)thrownewIllegalStateException("Alreadyexecuted.");

executed=true;

call=rawCall;

failure=creationFailure;

if(call==nullfailure==null){

try{

//創(chuàng)建一個OkHttp的Request對象請求

call=rawCall=createRawCall();

}catch(Throwablet){

throwIfFatal(t);

failure=creationFailure=t;

if(failure!=null){

callback.onFailure(this,failure);

return;

if(canceled){

call.cancel();

call.enqueue(

newokhttp3.Callback(){

@Override

publicvoidonResponse(okhttp3.Callcall,okhttp3.ResponserawResponse){

ResponseTresponse;

try{

//解析網(wǎng)絡(luò)請求返回的數(shù)據(jù)

response=parseResponse(rawResponse);

}catch(Throwablee){

throwIfFatal(e);

callFailure(e);

return;

try{

callback.onResponse(OkHttpCall.this,response);

}catch(Throwablet){

throwIfFatal(t);

t.printStackTrace();//TODOthisisnotgreat

@Override

publicvoidonFailure(okhttp3.Callcall,IOExceptione){

callFailure(e);

privatevoidcallFailure(Throwablee){

try{

callback.onFailure(OkHttpCall.this,e);

}catch(Throwablet){

throwIfFatal(t);

t.printStackTrace();//TODOthisisnotgreat

}

ResponseTparseResponse(okhttp3.ResponserawResponse)throwsIOException{

ResponseBodyrawBody=rawResponse.body();

//Removethebody'ssource(theonlystatefulobject)sowecanpasstheresponsealong.

rawResponse=

rawResponse

.newBuilder()

.body(newNoContentResponseBody(rawBody.contentType(),rawBody.contentLength()))

.build();

intcode=rawResponse.code();

//根據(jù)響應(yīng)返回的狀態(tài)碼進行處理

if(code200||code=300){

try{

//BuffertheentirebodytoavoidfutureI/O.

ResponseBodybufferedBody=Utils.buffer(rawBody);

returnResponse.error(buf

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論