配色: 字号:
Android网络之Retrofit2.0使用和解析
2016-12-17 | 阅:  转:  |  分享 
  
Android网络之Retrofit2.0使用和解析



Retrofit2在项目中的使用



Androidstudio项目添加依赖



compile''com.squareup.retrofit2:retrofit:2.0.1''



项目中使用样例



定义HTTPAPI使用接口



publicinterfaceGitHubService{

@GET("users/{user}/repos")

Call>listRepos(@Path("user")Stringuser);

}



通过在接口上添加注解的方式来表示如何处理网络请求。

Retrofit支持5中类型的注解:GET,POST,PUT,DELETE和HEAD.

可以使用不带参数的urljava@GET("users/list"),也可以使用带参数的urljava@GET("users/list?sort=desc")

构造Retrofit实例



Retrofitretrofit=newRetrofit.Builder()

.baseUrl("https://api.github.com/")

.build();

GitHubServiceservice=retrofit.create(GitHubService.class);



创建同步或异步HTTP请求到远程网络服务器



Call>repos=service.listRepos("octocat");



定制数据类型转换器



Gson:com.squareup.retrofit2:converter-gson

Jackson:com.squareup.retrofit2:converter-jackson

Moshi:com.squareup.retrofit2:converter-moshi

Protobuf:com.squareup.retrofit2:converter-protobuf

Wire:com.squareup.retrofit2:converter-wire

SimpleXML:com.squareup.retrofit2:converter-simplexml

Scalars(primitives,boxed,andString):com.squareup.retrofit2:converter-scalars

Retrofitretrofit=newRetrofit.Builder()

.baseUrl("https://api.github.com")

.addConverterFactory(GsonConverterFactory.create())

.build();



GitHubServiceservice=retrofit.create(GitHubService.class);



Retrofit使用扩展



自定义Gson类型转换器



/

{

"resultcode":0,

"resultmsg":"请求成功",

"result":{}

}

/

publicclassWrapper{

publicintresultcode;

publicStringresultmsg;

publicObjectresult;

publicstaticclassJsonAdapterimplementsJsonDeserializer{

@Override

publicWrapperdeserialize(JsonElementjson,TypetypeOfT,JsonDeserializationContextcontext)throwsJsonParseException{

try{

StringjsonRoot=json.getAsJsonObject().toString();

Wrapperwrapper=newWrapper();

JSONObjectjsobRespData=newJSONObject(jsonRoot);

wrapper.resultcode=jsobRespData.getInt("resultcode");

wrapper.resultmsg=jsobRespData.getString("resultmsg");

wrapper.result=jsobRespData.get("result");

returnwrapper;

}catch(JSONExceptione){

thrownewJsonParseException(e);

}

}

}

添加到Retrofit当中



Gsongson=newGsonBuilder()

.registerTypeAdapter(Wrapper.class,newWrapper.JsonAdapter())

.create();

Retrofitretrofit=newRetrofit.Builder()

.baseUrl("https://api.github.com")

.addConverterFactory(GsonConverterFactory.create(gson))

.build();



GitHubServiceservice=retrofit.create(GitHubService.class);



请求时添加head信息



在定义请求接口时添加:



@Headers("Cache-Control:max-age=640000")

@GET("widget/list")

Call>widgetList();



@Headers({

"Accept:application/vnd.github.v3.full+json",

"User-Agent:Retrofit-Sample-App"

})

@GET("users/{username}")

CallgetUser(@Path("username")Stringusername);



@GET("user")

CallgetUser(@Header("Authorization")Stringauthorization)



Retrofit依赖

如果所示在Retrofit2.0中只支持okhttp,所以另一种方法是在okhttp的拦截器中addheader。



Retrofit2源码解析



Retrofit请求框架实现了高度的解耦,通过解析注解的得到的代理类生成http请求,然后将请求交给OkHttp。通过在Retrofit创建时生成的Converter再将OkHttp返回的数据进行类型转换得到自己需要的数据。现在Rxjava响应式编程已经广泛应用,在使用Retrofit时也会结合RxJava使编码更加简单、高效。

一张图简单描述一下Retrofit的工作原理:

Retrofit工作原理



定义网络请求接口



publicinterfaceGitHubService{

@GET("users/{user}/repos")

Call>listRepos(@Path("user")Stringuser);

}



创建Retrofit实例



Retrofitretrofit=newRetrofit.Builder()

.baseUrl("https://api.github.com")

//支持RxJava

.addCallAdapterFactory(RxJavaCallAdapterFactory.create())

.addConverterFactory(ByteArrayConverterFactory.create())

.addConverterFactory(JSONObjectResponseConverterFactory.create())

.addConverterFactory(StringResponseConverterFactory.create())

//支持对象转json串

.addConverterFactory(GsonConverterFactory.create())

.build();



设置BaseUrl

添加CallAdapterFactory

添加converterFactory

此时也可以设置自定义的okHttpclient

接下来我们看



GitHubServiceservice=retrofit.create(GitHubService.class);



Retrofit.create方法的详细介绍



publicTcreate(finalClassservice){

//判断定义的接口服务是否可用

Utils.validateServiceInterface(service);

if(validateEagerly){

eagerlyValidateMethods(service);

}

return(T)Proxy.newProxyInstance(service.getClassLoader(),newClass[]{service},

newInvocationHandler(){

//判断Android,IOS,java8

privatefinalPlatformplatform=Platform.get();



@OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object...args)

throwsThrowable{

//如果是对象里的方法直接调用

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

returnmethod.invoke(this,args);

}

/

对java8做兼容,android和ios值恒为false

/

if(platform.isDefaultMethod(method)){

returnplatform.invokeDefaultMethod(method,service,proxy,args);

}

//主要看这三行代码

/

1、生成获取缓存中的method对应的ServiceMethod或者生产method对应的ServiceMethod

2、生成OkHttpCall的实例

3、根据生成的ServiceMethod实例中的callAdapter对象,调用callAdapter.adapt方法创建

对应的Observable

/

ServiceMethodserviceMethod=loadServiceMethod(method);

OkHttpCallokHttpCall=newOkHttpCall<>(serviceMethod,args);

returnserviceMethod.callAdapter.adapt(okHttpCall);

}



Platfrom的获取



Platfrom



classPlatform{

//这个方法Android中为Plafrom默认的

//Java8返回的是method.isDefault(),熟悉Java8的都知道这是Java8的新特性。。

booleanisDefaultMethod(Methodmethod){

returnfalse;

}

//这个方法Android中有自己默认的实现MainThreadExecutor

ExecutordefaultCallbackExecutor(){

returnnull;

}

staticclassAndroidextendsPlatform{

@Override

publicExecutordefaultCallbackExecutor(){

returnnewMainThreadExecutor();

}



@Override

CallAdapter.FactorydefaultCallAdapterFactory(ExecutorcallbackExecutor){

returnnewExecutorCallAdapterFactory(callbackExecutor);

}

//Rx默认请求方式都是同步请求,所以我们在发出请求和请求结果回来的时候切换线程

staticclassMainThreadExecutorimplementsExecutor{

privatefinalHandlerhandler=newHandler(Looper.getMainLooper());

@Override

publicvoidexecute(Runnabler){

handler.post(r);

}

}

}



ServiceMethod对象的生成



先看一张我debug时候的ServiceMethod的图

ServiceMethod



ServiceMethod的获取



/Retrofit.java

首先从serviceMethodCache缓存中获取,如果为null则创建

/

ServiceMethodloadServiceMethod(Methodmethod){

ServiceMethodresult;

synchronized(serviceMethodCache){

result=serviceMethodCache.get(method);

if(result==null){

result=newServiceMethod.Builder(this,method).build();

serviceMethodCache.put(method,result);

}

}

returnresult;

}



ServiceMethod的创建



finalclassServiceMethod{

//部分代码省略

ServiceMethod(Builderbuilder){

this.callFactory=builder.retrofit.callFactory();

this.callAdapter=builder.callAdapter;

this.baseUrl=builder.retrofit.baseUrl();

this.responseConverter=builder.responseConverter;

this.httpMethod=builder.httpMethod;

this.relativeUrl=builder.relativeUrl;

this.headers=builder.headers;

this.contentType=builder.contentType;

this.hasBody=builder.hasBody;

this.isFormEncoded=builder.isFormEncoded;

this.isMultipart=builder.isMultipart;

this.parameterHandlers=builder.parameterHandlers;

}

staticfinalclassBuilder{

publicBuilder(Retrofitretrofit,Methodmethod){

this.retrofit=retrofit;

this.method=method;

this.methodAnnotations=method.getAnnotations();

this.parameterTypes=method.getGenericParameterTypes();

this.parameterAnnotationsArray=method.getParameterAnnotations();

}



publicServiceMethodbuild(){

//创建CallAdapter

callAdapter=createCallAdapter();

responseType=callAdapter.responseType();

if(responseType==Response.class||responseType==okhttp3.Response.class){

throwmethodError("''"

+Utils.getRawType(responseType).getName()

+"''isnotavalidresponsebodytype.DidyoumeanResponseBody?");

}

//创建Converter

responseConverter=createResponseConverter();

for(Annotationannotation:methodAnnotations){

parseMethodAnnotation(annotation);

}

//

returnnewServiceMethod<>(this);

}



privateCallAdaptercreateCallAdapter(){

TypereturnType=method.getGenericReturnType();

//

Annotation[]annotations=method.getAnnotations();

try{

//调用retrofit中的方法进行创建

returnretrofit.callAdapter(returnType,annotations);

}catch(RuntimeExceptione){//Wideexceptionrangebecausefactoriesareusercode.

throwmethodError(e,"Unabletocreatecalladapterfor%s",returnType);

}

}

privateConvertercreateResponseConverter(){

Annotation[]annotations=method.getAnnotations();

try{

//调用retrofit中的方法进行创建

returnretrofit.responseBodyConverter(responseType,annotations);

}catch(RuntimeExceptione){//Wideexceptionrangebecausefactoriesareusercode.

throwmethodError(e,"Unabletocreateconverterfor%s",responseType);

}

}

}



CallAdapter的创建



publicCallAdaptercallAdapter(TypereturnType,Annotation[]annotations){

returnnextCallAdapter(null,returnType,annotations);

}



publicCallAdapternextCallAdapter(CallAdapter.FactoryskipPast,TypereturnType,

Annotation[]annotations){

checkNotNull(returnType,"returnType==null");

checkNotNull(annotations,"annotations==null");

intstart=adapterFactories.indexOf(skipPast)+1;

for(inti=start,count=adapterFactories.size();i
CallAdapteradapter=adapterFactories.get(i).get(returnType,annotations,this);

if(adapter!=null){

returnadapter;

}

}

//

}



在创建Retrofit的时候我们添加过.addCallAdapterFactory(RxJavaCallAdapterFactory.create()),这是我们会调用RxJavaCallAdapterFactory.get方法获取CallAdapter,通过源代码我们可以找到其返回的是newSimpleCallAdapter(observableType,scheduler)。



Converter的创建



publicConverterrequestBodyConverter(Typetype,

Annotation[]parameterAnnotations,Annotation[]methodAnnotations){

returnnextRequestBodyConverter(null,type,parameterAnnotations,methodAnnotations);

}



publicConverternextRequestBodyConverter(Converter.FactoryskipPast,

Typetype,Annotation[]parameterAnnotations,Annotation[]methodAnnotations){

checkNotNull(type,"type==null");

checkNotNull(parameterAnnotations,"parameterAnnotations==null");

checkNotNull(methodAnnotations,"methodAnnotations==null");

intstart=converterFactories.indexOfwww.wang027.com(skipPast)+1;

for(inti=start,count=converterFactories.size();i
Converter.Factoryfactory=converterFactories.get(i);

Converterconverter=

factory.requestBodyConverter(type,parameterAnnotations,methodAnnotations,this);

if(converter!=null){

//noinspectionunchecked

return(Converter)converter;

}

}

//



相同的在创建Retrofit的时候我们也添加过许多的ConverterFactory,在寻找相匹配的Converter时我们是通过遍历在寻找到第一个合适的Converter返回。什么叫做合适的Converter,即该ConverterFactory能产生出匹配服务接口注解和返回类型。



retrofit的构造器中默认添加的适配器和转化器



publicstaticfinalclassBuilder{

privatePlatformplatform;

privateokhttp3.Call.FactorycallFactory;

privateHttpUrlbaseUrl;

privateListconverterFactories=newArrayList<>();

privateListadapterFactories=newArrayList<>();

privateExecutorcallbackExecutor;

privatebooleanvalidateEagerly;



Builder(Platformplatform){

this.platform=platform;

//Addthebuilt-inconverterfactoryfirst.Thispreventsoverridingitsbehaviorbutalso

//ensurescorrectbehaviorwhenusingconvertersthatconsumealltypes.

//自动回添加加默认的转化器

converterFactories.add(newBuiltInConverters());

}

//

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.

ListadapterFactories=newArrayList<>(this.adapterFactories);

//添加一个默认的适配器(Android、IOS、Java8)

adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));



//Makeadefensivecopyoftheconverters.

ListconverterFactories=newArrayList<>(this.converterFactories);



returnnewRetrofit(callFactory,baseUrl,converterFactories,adapterFactories,

callbackExecutor,validateEagerly);



具体怎么从Factory中获取对应的Converter和Adapter我们从代码中可以直观的看到。



OkHttpCall的创建



OkHttpCall(ServiceMethodserviceMethod,Object[]args){

this.serviceMethod=serviceMethod;

this.args=args;

}



网络请求



请求的准备



serviceMethod.callAdapter.adapt(okHttpCall)对应SimpleCallAdapter.adapt



staticfinalclassSimpleCallAdapterimplementsCallAdapter>{

privatefinalTyperesponseType;

privatefinalSchedulerscheduler;

SimpleCallAdapter(TyperesponseType,Schedulerscheduler){

this.responseType=responseType;

this.scheduler=scheduler;

}

@OverridepublicTyperesponseType(){

returnresponseType;

}

@OverridepublicObservableadapt(Callcall){

//创建请求的观察者,返回我们需要的Ovservable

Observableobservable=Observable.create(newCallOnSubscribe<>(call))//

.lift(OperatorMapResponseToBodyOrError.instance());

if(scheduler!=null){

returnobservable.subscribeOn(scheduler);

}

returnobservable;

}



staticclassAndroidextendsPlatform{

@Override

publicExecutordefaultCallbackExecutor(){

returnnewMainThreadExecutor();

}

@Override

CallAdapter.FactorydefaultCallAdapterFactory(ExecutorcallbackExecutor){

returnnewExecutorCallAdapterFactory(callbackExecutor);

}

staticclassMainThreadExecutorimplementsExecutor{

privatefinalHandlerhandler=newHandler(Looper.getMainLooper());

@Override

publicvoidexecute(Runnabler){

handler.post(r);

}

}

}

/

因为默认的执行线程为主线程,所以我们要切换到subscribeOn(Schedulers.io())线程从而达到异步的目的。

然后通过observeOn(AndroidSchedulers.mainThread())将线程切回UI线程。

当Okhttp请求完数据并进行相应的convert之后,就可以在UI处理相应的逻辑。

/

service.listRepos("octocat")

.observeOn(AndroidSchedulers.mainThread())

.subscribeOn(Schedulers.io())

.subscribe(list->{

if(list!=null){

//TODO取得数据后逻辑处理

}



请求的发起



回到CallAdapt方法,创建Observable,而newCallOnSubscribe<>(call)生成了一个OnSubscribe()的实例,而OnSubscribe继承自Action1,其只包含一个call()方法,而这个call是在CallOnSubscribe中实现:



staticfinalclassCallOnSubscribeimplementsObservable.OnSubscribe>{

privatefinalCalloriginalCall;

CallOnSubscribe(CalloriginalCall){

this.originalCall=originalCall;

}

@Overridepublicvoidcall(finalSubscriber>subscriber){

//SinceCallisaone-shottype,cloneitforeachnewsubscriber.

Callcall=originalCall.clone();



//Wrapthecallinahelperwhichhandlesbothunsubscriptionandbackpressure.

RequestArbiterrequestArbiter=newRequestArbiter<>(call,subscriber);

subscriber.add(Subscriptions.create(requestArbiter));

subscriber.setProducer(requestArbiter);



首先clone了一份Call,然后生成了RequestArbiter,他继承自AtomicBoolean,实现了Subscription,Producer接口,Producer只有一个request方法;一般实现该接口的类,都会包含一个Subscriber对象和一个待处理的数据:



staticfinalclassRequestArbiterextendsAtomicBooleanimplementsAction0,

Producer{

privatefinalCallcall;

privatefinalSubscriber>subscriber;

RequestArbiter(Callcall,Subscriber>subscriber){

this.call=call;

this.subscriber=subscriber;

}

@Override

publicvoidrequest(longn){

if(n<0){

thrownewIllegalArgumentException("n<0:"+n);

}

if(n==0){

return;//Nothingtodowhenrequesting0.

}

if(!compareAndSet(false,true)){

return;//Requestwasalreadytriggered.

}

try{

//进行网络请求

Responseresponse=call.execute();

if(!subscriber.isUnsubscribed()){

subscriber.onNext(response);

}

}catch(Throwablet){

Exceptions.throwIfFatal(t);

if(!subscriber.isUnsubscribed()){

subscriber.onError(t);

}

return;

}

if(!subscriber.isUnsubscribed()){

subscriber.onCompleted();

}

}



@Override

publicvoidcall(){

call.cancel();

}



请求的执行



回顾创建Retrofit.create()代码中serviceMethod.callAdapter.adapt(okHttpCall),所以上面的call.execute()就是OkHttpCall.execute



publicResponseexecute()throwsIOException{

okhttp3.Callcall;

synchronized(this){

if(executed)

thrownewIllegalStateException("Alreadyexecuted.");

executed=true;

if(creationFailure!=null){

if(creationFailureinstanceofIOException){

throw(IOException)creationFailure;

}else{

throw(RuntimeException)creationFailure;

}

}

call=rawCall;

if(call==null){

try{

//获取okhttp实例

call=rawCall=createRawCall();

}catch(IOException|RuntimeExceptione){

creationFailure=e;

throwe;

}

}

}

if(canceled){

call.cancel();

}

//执行okhttp请求

return(parseResponse(call.execute()));

}



privateokhttp3.CallcreateRawCall()throwsIOException{

Requestrequest=serviceMethod.toRequest(args);

//serviceMethod构造中this.callFactory=builder.retrofit.callFactory();

okhttp3.Callcall=serviceMethod.callFactory.newCall(request);

if(call==null){

thrownewNullPointerException("Call.Factoryreturnednull.");

}

return(call);



请求的OkHttpClient实例获取



publicokhttp3.Call.FactorycallFactory(){

returncallFactory;

}

publicBuildercallFactory(okhttp3.Call.Factoryfactory){

this.callFactory=checkNotNull(factory,"factory==null");

returnthis;

}

//使用自定义OkHttpClient

publicBuilderclient(OkHttpClientclient){

returncallFactory(checkNotNull(client,"client==null"));

}



publicRetrofitbuild(){

if(baseUrl==null){

thrownewIllegalStateException("BaseURLrequired.");

}

okhttp3.Call.FactorycallFactory=this.callFactory;

//没有自定义OkHttpClient,则会新创建一个

if(callFactory==null){

callFactory=newOkHttpClient();

}

ExecutorcallbackExecutor=this.callbackExecutor;

if(callbackExecutor==null){

callbackExecutor=platform.defaultCallbackExecutor();

}

ListadapterFactories=newArrayList<>(this.adapterFactories);

adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

ListconverterFactories=newArrayList<>(this.converterwww.baiyuewang.netFactories);

return(newRetrofit(callFactory,baseUrl,converterFactories,adapterFactories,

callbackExecutor,validateEagerly));

}

}

请求结果的处理



ResponseparseResponse(okhttp3.ResponserawResponse)throwsIOException{

ResponseBodyrawBody=rawResponse.body();

rawResponse=rawResponse.newBuilder()

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

.build();

intcode=rawResponse.code();

if(code<200||code>=300){

try{

ResponseBodybufferedBody=Utils.buffer(rawBody);

return(Response.error(bufferedBody,rawResponse));

}finally{

rawBody.close();

}

}

if(code==204||code==205){

return(Response.success(null,rawResponse));

}

ExceptionCatchingRequestBodycatchingBody=newExceptionCatchingRequestBody(rawBody);

try{

//使用Converter将返回结果转化为接口返回的数据格式类型

Tbody=serviceMethod.toResponse(catchingBody);

//包装成Response并返回

return(Response.success(body,rawResponse));

}catch(RuntimeExceptione){

catchingBody.throwIfCaught();

throwe;

}



还记得创建Observable时Observableobservable=Observable.create(newCallOnSubscribe<>(call)).lift(OperatorMapResponseToBodyOrError.instance());,OperatorMapResponseToBodyOrError将包装的Response中的body取出来并进行发射。



总结



现在随着Rxjava响应式编程越来越多的程序猿使用,自己也开始接触和使用。Retrofit+Rxjava+okhttp是时下比较受欢迎的网络请求框架,其源代码并不是很多,其底层网络通信时交由OkHttp来完成的,但是Retrofit运用了大量的设计模式,代码逻辑很清晰,笔者以前用的是AsyncHttpClient作为app的网络请求框架,其源码也没自己的研究过。但看完Retrofit代码之后觉得收获很大,建议如果感兴趣可以抽时间仔细的阅读。

献花(0)
+1
(本文系thedust79首藏)