




版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 西方政治制度對移民公民化的影響試題及答案
- 叉車全部考試題庫及答案
- 2025年環(huán)境政策與地方實施考試題及答案
- 軟件設(shè)計師考試團隊項目展示與試題及答案
- 兔玩網(wǎng)java面試題及答案
- java程序員進bat面試題及答案
- 動畫駕駛考試題及答案
- 人大哲學(xué)面試題及答案
- 華泰證券java面試題及答案
- 自我反思的抒情作文5篇
- 世界環(huán)境日主題課件
- 職業(yè)道德與法治 第13課《學(xué)會依法維權(quán)》第一框課件《依法理性維權(quán)》
- 鄰近鐵路營業(yè)線施工安全監(jiān)測技術(shù)規(guī)程 (TB 10314-2021)
- 婦科常見病科普知識講座
- 城市土壤主要類型及特點
- 賓館財務(wù)安全管理制度
- 《康復(fù)護理學(xué)基礎(chǔ)》期末考試復(fù)習(xí)題庫(含答案)
- 寶鋼武鋼并購重組案例研究
- 胰島素的種類及應(yīng)用(共26張PPT)
- 眩暈診療方案總結(jié)優(yōu)化
- 轉(zhuǎn)讓魚塘股份合同范本
評論
0/150
提交評論