Retrofit的使用与深入学习(下)

来源:互联网 发布:淘宝同行恶意投诉售假 编辑:程序博客网 时间:2024/06/05 22:23

注意:以下分析都是基于Retrofit2
转载请注明出处:http://blog.csdn.net/evan_man/article/details/51320637

    本节是《Retrofit的使用与深入学习》的进阶版本,着重讲解一下Retrofit中的Converter.Factory和CallAdapter.Factory两个对象。正式介绍之前,首先回顾一下这两个抽象类都定义了哪些方法:
public interface CallAdapter<T> {  Type responseType();   //该请求适配器返回的数据类型  <R> T adapt(Call<R> call);  //该请求适配器对原始Call的再次封装,如Call<R>到Observable<R>,这里的Call<R>在retrofit2中都是OkHttpCall对象  abstract class Factory {    public abstract CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit); //获取网络请求适配器    protected static Type getParameterUpperBound(int index, ParameterizedType type) { return Utils.getParameterUpperBound(index, type); }     //Example:完成Map<String, ? extends Runnable> 到  Runnable的转变;第i个参数的最上层的数据类型    protected static Class<?> getRawType(Type type) {  return Utils.getRawType(type); }     //Example:完成List<? extends Runnable> 到 List.class的转变;  即得到最外层的那个数据类型  }}public interface Converter<F, T> {  T convert(F value) throws IOException;  abstract class Factory {    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { return null; } //对响应数据的转换    public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return null; } //对请求数据的转换    public Converter<?, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) {  return null;  }  //String类型转换  }}
    本节我们将先对Retrofit默认网络请求适配器ExecutorCallAdapterFactoryRxJavaCallAdapterFactory进行介绍,随后介绍Retrofit的默认内容转换器BuiltInConvertersGsonConverterFactory。在此需要在此强调的是Retrofit的ArrayList<CallAdapter.Factory> adapterFactories集合中ExecutorCallAdapterFactory位于该集合的末尾。Retrofit的ArrayList<Converter.Factory> converterFactories集合中BuiltInConverters位于该集合的首位。在接口方法Method向ServiceMethod的转化过程中,都是从adapterFactories和converterFactories集合的首位开始往后找的,因此集合中的工厂位置越靠前就拥有越高的使用权限因为GsonConverterFactory它能对任何数据都可以进行转换(最多转换异常嘛),因此Retrofit作者特别强调一定将GsonConverterFactory添加到Retrofit的converterFactories集合的末尾。

ExecutorCallAdapterFactory.class

final class ExecutorCallAdapterFactory extends CallAdapter.Factory
ExecutorCallAdapterFactory()@ExecutorCallAdapterFactory.class
类只有一个域,即回调方法执行器
final Executor callbackExecutor;ExecutorCallAdapterFactory(Executor callbackExecutor) {    this.callbackExecutor = callbackExecutor;}
只有一个用于返回CallAdapter<Call<?>>对象的get方法
get()@ExecutorCallAdapterFactory.class
public CallAdapter<Call<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {    if (getRawType(returnType) != Call.class) {  return null; }     final Type responseType = Utils.getCallResponseType(returnType);        return new CallAdapter<Call<?>>() {      @Override public Type responseType() { return responseType; }       @Override public <R> Call<R> adapt(Call<R> call) { return new ExecutorCallbackCall<>(callbackExecutor, call); } //note1    };  }
1、创建一个回调请求执行器,该执行器实现了Call<T>接口
static final class ExecutorCallbackCall<T> implements Call<T>
ExecutorCallbackCall.class@ExecutorCallAdapterFactory.class
final Executor callbackExecutor; //回调方法执行器final Call<T> delegate;//网络请求实体ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {      this.callbackExecutor = callbackExecutor;      this.delegate = delegate;}@Override public boolean isExecuted() { return delegate.isExecuted(); }@Override public Call<T> clone() {  return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone()); }@Override public Request request() { return delegate.request(); }@Override public Response<T> execute() throws IOException {  return delegate.execute(); } //note1@Override public void enqueue(final Callback<T> callback) {//note2      if (callback == null) throw new NullPointerException("callback == null");      delegate.enqueue(new Callback<T>() {        @Override public void onResponse(Call<T> call, final Response<T> response) {          callbackExecutor.execute(new Runnable() {             @Override public void run() {              if (delegate.isCanceled()) {  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(new Runnable() {            @Override public void run() {  callback.onFailure(ExecutorCallbackCall.this, t); }           });        }      });}
1、同步请求直接调用OkHttpCall的同名方法去执行
2、异步请求将相应的结果交给callbackExecutor回调执行器去执行
    综上我们对ExecutorCallAdapterFactory.class的总结就是,该对象存储一个回调执行器;通过该工厂的get方法得到的CallAdapter对象类型是固定的,跟returnType,annotations等参数都没有关系。CallAdapter对象的adapt方法返回的Call<T>对象基本透明,网络请求都是通过调用adapt传入参数Call<T>对象的同名方法。

RxJavaCallAdapterFactory.class

public final class RxJavaCallAdapterFactory extends CallAdapter.Factory
RxJavaCallAdapterFactory()@RxJavaCallAdapterFactory.class
private final Scheduler scheduler;private RxJavaCallAdapterFactory(Scheduler scheduler) {    this.scheduler = scheduler;}public static RxJavaCallAdapterFactory create() {    return new RxJavaCallAdapterFactory(null);}
scheduler默认是一个null,用于设计Observable.subscribeOn(scheduler);即Subscriber对象的onStart方法执行线程,一般没什么卵用。
get()@RxJavaCallAdapterFactory.class
public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {    Class<?> rawType = getRawType(returnType); //note1    String canonicalName = rawType.getCanonicalName(); //note2    boolean isSingle = "rx.Single".equals(canonicalName); //note3    boolean isCompletable = "rx.Completable".equals(canonicalName);    if (rawType != Observable.class && !isSingle && !isCompletable) { //note4      return null;    }    if (!isCompletable && !(returnType instanceof ParameterizedType)) {      String name = isSingle ? "Single" : "Observable";      throw new IllegalStateException(name + " return type must be parameterized" + " as " + name + "<Foo> or " + name + "<? extends Foo>");     }    if (isCompletable) {        return CompletableHelper.createCallAdapter(scheduler);    }    CallAdapter<Observable<?>> callAdapter = getCallAdapter(returnType, scheduler); //note5    if (isSingle) {      return SingleHelper.makeSingle(callAdapter);    }    return callAdapter;}
1、获取返回值类型的最外层的类;对于List<? extends Runnable>就会得到List.class;
2、返回该类含包名的名字;参考
3、是否是rx.Single 、rx.Completable两个类
4、如果返回值类型最外层不是rx.Single 、rx.Completable、Observable则该RxJavaCallAdapterFactory不对其进行处理;将交给Retrofit的adapterFactories集合中的下一个CallAdapter.Factory进行处理。
5、对于Completable<?> Single<?> Observable<?>我们只介绍最后一个Observable<?>

getCallAdapter()@RxJavaCallAdapterFactory.class
private CallAdapter<Observable<?>> getCallAdapter(Type returnType, Scheduler scheduler) {    Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType); //note1    Class<?> rawObservableType = getRawType(observableType); //note2    if (rawObservableType == Response.class) {      if (!(observableType instanceof ParameterizedType)) {        throw new IllegalStateException("Response must be parameterized"  + " as Response<Foo> or Response<? extends Foo>");       }      Type responseType = getParameterUpperBound(0, (ParameterizedType) observableType); //note3      return new ResponseCallAdapter(responseType, scheduler); //note4    }    if (rawObservableType == Result.class) {      if (!(observableType instanceof ParameterizedType)) {        throw new IllegalStateException("Result must be parameterized"  + " as Result<Foo> or Result<? extends Foo>");       }      Type responseType = getParameterUpperBound(0, (ParameterizedType) observableType);      return new ResultCallAdapter(responseType, scheduler); //note5    }    return new SimpleCallAdapter(observableType, scheduler); //note6  }
1、Observable<Response<T>> 到Response<T>的转变;
2、Response<T> 到 Response的转变;
3、Response<T> 到 T 的转变;
4、Observable<Response<? extends T>>创建一个ResponseCallAdapter对象
5、Observable<Result<? extends T>>创建一个ResultCallAdapter对象
6、默认创建一个SimpleCallAdapter对象,先对该对象进行介绍
SimpleCallAdapter.class@RxJavaCallAdapterFactory.class
static final class SimpleCallAdapter implements CallAdapter<Observable<?>> {    private final Type responseType;    private final Scheduler scheduler;    SimpleCallAdapter(Type responseType, Scheduler scheduler) {      this.responseType = responseType;      this.scheduler = scheduler;    }    @Override public Type responseType() {      return responseType;    }    @Override public <R> Observable<R> adapt(Call<R> call) {      Observable<R> observable = Observable.create(new CallOnSubscribe<>(call)) // note1          .lift(OperatorMapResponseToBodyOrError.<R>instance()); //note2      if (scheduler != null) {        return observable.subscribeOn(scheduler); //note3      }      return observable;    }}
哈哈哈,很熟悉的RxJava操作——lift&Operator,如果看到这里你没有眼前一亮或者不懂博主的自言自语,那么十分推荐去看看本人的另外一篇博客《RxJava的使用与深入学习》,因为接下来的讲解都是默认你知道RxJava的内部工作原理进行讲解的,不然你也可以硬着头皮往下看。
1、CallOnSubscribe<>(Call<R> call)一猜就知道在OnSubscribe的call方法中会利用参数call获取一个最原始的网络Response<R>数据,不信你看CallOnSubscribe.class的call方法源码 (后面有给出);
2、OperatorMapResponseToBodyOrError是对Subscribe对象的一次封装,封装后的Subscribe对象会对前面得到的Response<R>进行一定的预处理后(从Operator的名字来看就是对Response<R>状态进行判断),再传递给后面的Subscribe对象进行处理;
3、如果scheduler不为空则用该scheduler设置Observable的subscribe方法的执行线程

CallOnSubscribe.class@RxJavaCallAdapterFactory.class
static final class CallOnSubscribe<T> implements Observable.OnSubscribe<Response<T>> {    private final Call<T> originalCall; //note1    CallOnSubscribe(Call<T> originalCall) {      this.originalCall = originalCall;    }    @Override public void call(final Subscriber<? super Response<T>> subscriber) { //note1.5      Call<T> call = originalCall.clone();      RequestArbiter<T> requestArbiter = new RequestArbiter<>(call, subscriber); //note2      subscriber.add(requestArbiter);      subscriber.setProducer(requestArbiter); //note3    }}
1、构造该方法是传入的OkHttpCall对象,用于执行网络请求
1.5、该SubscribeOn能处理的Subscribe对象是Subscriber<? super Response<T>> 类型
2、利用OkHttpCall和Subscriber<? super Response<T>>创建一个事件生成对象
3、一般该方法的结果就是调用requestArbiter.request(Integer.MAX_VALUE);所以我们接下来看看RequestArbiter类的request方法是如何定义的。

RequestArbiter.class@RxJavaCallAdapterFactory.class
static final class RequestArbiter<T> extends AtomicBoolean implements Subscription, Producer {    private final Call<T> call; //构造该对象时传入的OkHttpCall    private final Subscriber<? super Response<T>> subscriber; //构造该对象时传入的Subscriber<? super Response<T>>    RequestArbiter(Call<T> call, Subscriber<? super Response<T>> subscriber) {      this.call = call;      this.subscriber = subscriber;    }    @Override public void request(long n) {      if (n < 0) throw new IllegalArgumentException("n < 0: " + n);      if (n == 0) return; // Nothing to do when requesting 0.      if (!compareAndSet(false, true)) return; // Request was already triggered.      try {        Response<T> response = call.execute(); //note1        if (!subscriber.isUnsubscribed()) { subscriber.onNext(response); }  //note2      } catch (Throwable t) {        Exceptions.throwIfFatal(t);        if (!subscriber.isUnsubscribed()) { subscriber.onError(t);}  //note3        return;      }       if (!subscriber.isUnsubscribed()) { subscriber.onCompleted(); }  //note4    }    @Override public void unsubscribe() {  call.cancel(); }  //note5    @Override public boolean isUnsubscribed() {   return call.isCanceled(); }  //note6}
1、通过OkHttpCall的execute——同步请求,获取Response<T>对象
2、如果当前subscribe没有解绑,调用Subscriber<? super Response<T>>的onNext方法处理上面得到的Response<T>对象
3、如果当前subscribe没有解绑,调用Subscriber<? super Response<T>>的onError方法处理异常t
4、如果当前subscribe没有解绑,调用Subscriber<? super Response<T>>的onCompleted()方法
5、如果当前subscribe要求解绑,调用OkHttpCall的cancel()方法断开连接
6、判断一个subscribe是否解绑,实则是判断OkHttpCall是否断开连接
发现没,如果使用Observable<T>进行网络访问,那么一旦Subscribe解除绑定就会断开网络连接,而且不再接收任何网络信息,这也是为什么Retrofit作者建议在Activity和Fragment中使用Retrofit+RxJava时一定要在onDestiny方法中调用subscription.unsubscribe()方法解除绑定的原因,即断开网络连接,回收网络资源。

到此为止我们分析完了SimpleCallAdapter.class@RxJavaCallAdapterFactory.class的note1,得到的Observable<R> 能接收Subscriber<? super Response<T>>类型的订阅者。接着我们继续分析note2的.lift(OperatorMapResponseToBodyOrError.<R>instance())操作。


OperatorMapResponseToBodyOrError.class

final class OperatorMapResponseToBodyOrError<T> implements Operator<T, Response<T>> {  private static final OperatorMapResponseToBodyOrError<Object> INSTANCE =  new OperatorMapResponseToBodyOrError<>();   static <R> OperatorMapResponseToBodyOrError<R> instance() {    return (OperatorMapResponseToBodyOrError<R>) INSTANCE;  }  @Override public Subscriber<? super Response<T>> call(final Subscriber<? super T> child) {//note1    return new Subscriber<Response<T>>(child) {      @Override public void onNext(Response<T> response) {         if (response.isSuccessful()) {          child.onNext(response.body()); //note2        } else {          child.onError(new HttpException(response)); //note3        }      }      @Override public void onCompleted() {        child.onCompleted();      }      @Override public void onError(Throwable e) {        child.onError(e);      }    };  }}
1、final Subscriber<? super T> child为被包装的Subscribe;call方法返回一个Subscriber<Response<T>>对象;被包装的Subscribe (child) 对象接收T类型数据,包装的Subscribe接收Response<T>类型数据;包装的Subscribe对象的onCompleted和onError方法内部实现就是直接调用被包装Subscribe (child) 对象的onCompleted和onError方法;包装的Subscribe对象的onNext方法稍微复杂点,我们往下看
2、如果Response<T>.isSuccessful()为真,则直接调用child.onNext(response.body()); 即让被包装Subscribe (child) 对象的onNext方法处理response.body()内容。
3、如果Response<T>.isSuccessful()为假,则直接调用child.onError(new HttpException(response));  即让被包装Subscribe child的onNext方法处理new HttpException(response);这也是为什么介绍Retrofit和RxJava配合使用的时候有如下的代码(Line10):
String username = "sarahjean";Observable<User> call = apiService.getUser(username);Subscription subscription = call.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<User>() {   ......  @Override  public void onError(Throwable e) {     if (e instanceof HttpException) {       HttpException response = (HttpException)e; //Line10       int code = response.code();    }  }});
不过你发现没,Subscribe只能接受到T类型的数据,即Response.body(),这样我们无法获取到Response<T>的Header部分的数据, 如网络请求的cookie等数据!!!!如果我们一定要获取cookie呢??答案肯定在我们之前漏掉的内容中。。。。回头看看,OperatorMapResponseToBodyOrError操作之前Subscribe接收的数据还是Response<T>,只是OperatorMapResponseToBodyOrError操作后将Response<T>的body取出,传给下一级Subscribe。顺着这个思路,在getCallAdapter()@RxJavaCallAdapterFactory.class中我们只对SimpleCallAdapter进行了介绍,还有两个CallAdapter没有介绍,它们分别是ResponseCallAdapter(responseType, scheduler)、ResultCallAdapter(responseType, scheduler)。没办法既然有需求我们就回头再看看这两个类型跟SimpleCallAdapter的区别。
ResponseCallAdapter.class@RxJavaCallAdapterFactory.class
static final class ResponseCallAdapter implements CallAdapter<Observable<?>> {    private final Type responseType;    private final Scheduler scheduler;    ResponseCallAdapter(Type responseType, Scheduler scheduler) {      this.responseType = responseType;      this.scheduler = scheduler;    }    @Override public Type responseType() {  return responseType;  }     @Override public <R> Observable<Response<R>> adapt(Call<R> call) {      Observable<Response<R>> observable = Observable.create(new CallOnSubscribe<>(call)); //note1      if (scheduler != null) {  return observable.subscribeOn(scheduler); }       return observable;    }}
1、ResponseCallAdapter相对于SimpleCallAdapter.class它缺少了.lift(OperatorMapResponseToBodyOrError.<R>instance())过程,而正如我们前面分析的,之所以我们之前的SimpleCallAdapter没能接收到Http网络响应的headers(如cookies)就是因为SimpleCallAdapter使用了OperatorMapResponseToBodyOrError操作!所以如果使用ResponseCallAdapter我们的Subscribe就能接收到Response<T>的全部数据了!使用ResponseCallAdapter对应客户端的方法返回类型为Observable<Response<T>>.
ResultCallAdapter.class@RxJavaCallAdapterFactory.class
static final class ResultCallAdapter implements CallAdapter<Observable<?>> {    private final Type responseType;    private final Scheduler scheduler;    ResultCallAdapter(Type responseType, Scheduler scheduler) {      this.responseType = responseType;      this.scheduler = scheduler;    }    @Override public Type responseType() {  return responseType; }     @Override public <R> Observable<Result<R>> adapt(Call<R> call) {      Observable<Result<R>> observable = Observable.create(new CallOnSubscribe<>(call)) // note1          .map(new Func1<Response<R>, Result<R>>() { //note2            @Override public Result<R> call(Response<R> response) {              return Result.response(response);            }          }).onErrorReturn(new Func1<Throwable, Result<R>>() {            @Override public Result<R> call(Throwable throwable) {              return Result.error(throwable);            }          });      if (scheduler != null) { return observable.subscribeOn(scheduler); }       return observable;    }}
1、此处和SimpleCallAdapter、ResponseCallAdapter都是一样的,能接收Subscribe<Response<T>>类型的Subscribe。
2、将Response<T>转换成一个Result<T>对象,Result<T>对象有两个域private final Response<T> response;   private final Throwable error;并有对应的方法返回这两个域。使用ResultCallAdapter对应客户端的方法返回类型为Observable<Result<T>>。

    到此为止我们对RxJavaCallAdapterFactory的介绍已经全部结束了。该工厂能够处理的方法返回值类型为Completable<?> 、Single<?> 和Observable<?>,其它类型交给Retrofit的ArrayList<CallAdapter.Factory>集合中后面的网络请求适配工厂处理。本节主要对Observable<?>进行了介绍,RxJavaCallAdapterFactory会为返回值类型为Observable<?>的方法创建一个CallAdapter<Observable<?>> 对象,而根据Observable内部的数据类型创建如下的继承自CallAdapter<Observable<?>> 的子对象ResponseCallAdapter、ResultCallAdapter和SimpleCallAdapter三个对象,它们的adapt方法返回值类型分别为Observable<Response<T>>、Observable<Result<T>>和Observable<T>三个类型。Observable<Response<T>>向Subscribe发送全部网络响应数据(可以从中读取headers的cookies)、Observable<T>只向Subscribe发送Response.body部分内容——经过转换器转好的T类型数据(不可以从中读取headers的cookies),但是Observable<T>会在内部保证只有在Response.isSuccessful为真时才调用subscribe的onNext方法。


上面介绍完了网络请求适配器工厂——CallAdapter.Factory,接着我们来学习内容转换工厂——Converter.Factory;首先看看Retrofit的内置的内容转换工厂
回顾一下内容工厂都需要实现哪些方法:
public interface Converter<F, T> {  T convert(F value) throws IOException;  abstract class Factory {    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { return null; } //对响应数据的转换    public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return null; } //对请求数据的转换    public Converter<?, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) {  return null;  }  //String类型转换  }}

BuiltInConverters.class

在Retrofit.Builder的构造器中就会向converterFactories集合中添加一个 BuiltInConverters对象。
final class BuiltInConverters extends Converter.Factory
responseBodyConverter()@BuiltInConverters.class
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,  Retrofit retrofit) { //note1    if (type == ResponseBody.class) {      if (Utils.isAnnotationPresent(annotations, Streaming.class)) {        return StreamingResponseBodyConverter.INSTANCE;      }      return BufferingResponseBodyConverter.INSTANCE;    }    if (type == Void.class) {      return VoidResponseBodyConverter.INSTANCE;    }    return null;}
1、需要注意的是这里的参数type是通过ServiceMethod的CallAdapter的responseType方法获得的Type;如我们定义的方法返回对象为Observable<Response<T>>,对应type为Response<T>;
该方法能够要求获取ResponseBody、Void类型的返回值进行处理,分别返回BufferingResponseBodyConverter、StreamingResponseBodyConverter、VoidResponseBodyConverter;如果不是ResponseBody类型或者Void类型则返回null交给下一个内容转换器工厂进行处理。
requestBodyConverter()@BuiltInConverters.class
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {     if (RequestBody.class.isAssignableFrom(Utils.getRawType(type))) { //note1      return RequestBodyConverter.INSTANCE;    }    return null;}
1、对于type为Request<T>;Utils.getRawType(type))得到Request
当请求报文的body类型为RequestBody时,该方法返回一个RequestBodyConverter对象。否则交给下一个内容转换器处理。
stringConverter()@BuiltInConverters.class
public Converter<?, String> stringConverter(Type type, Annotation[] annotations,  Retrofit retrofit) {     if (type == String.class) {      return StringConverter.INSTANCE;    }    return null;}
如果类型是String则创建一个StringConverter对象
往下我们依次看看BufferingResponseBodyConverter、StreamingResponseBodyConverter、VoidResponseBodyConverter、RequestBodyConverter和StringConverter的convert方法
StreamingResponseBodyConverter .class@BuiltInConverters.class
static final class StreamingResponseBodyConverter  implements Converter<ResponseBody, ResponseBody> {     static final StreamingResponseBodyConverter INSTANCE = new StreamingResponseBodyConverter();    @Override public ResponseBody convert(ResponseBody value) throws IOException {      return value;    }}
直接返回传入的ResponseBody类型数据。
BufferingResponseBodyConverter .class@BuiltInConverters.class
static final class BufferingResponseBodyConverter  implements Converter<ResponseBody, ResponseBody> {     static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();    @Override public ResponseBody convert(ResponseBody value) throws IOException {      try {  return Utils.buffer(value); }       finally { value.close(); }     }}
以缓存方式读取ResponseBody的内容,一次性全部读取出来。返回创建的ResponseBody,该对象已经将数据全部读取到了内存中。
VoidResponseBodyConverter .class@BuiltInConverters.class
static final class VoidResponseBodyConverter implements Converter<ResponseBody, Void> {    static final VoidResponseBodyConverter INSTANCE = new VoidResponseBodyConverter();    @Override public Void convert(ResponseBody value) throws IOException {      value.close();      return null;    }}
直接关闭ResponseBody,返回null
RequestBodyConverter.class@BuiltInConverters.class
static final class RequestBodyConverter implements Converter<RequestBody, RequestBody> {    static final RequestBodyConverter INSTANCE = new RequestBodyConverter();    @Override public RequestBody convert(RequestBody value) throws IOException {  return value;  } }
直接返回RequestBody类型数据
StringConverter.class@BuiltInConverters.class
static final class StringConverter implements Converter<String, String> {    static final StringConverter INSTANCE = new StringConverter();    @Override public String convert(String value) throws IOException { return value; } }
直接返回String数据
综上我们知道了,Retrofit内置的BuildInConverters只能处理RequestBody、ResponseBody和String类型数据,而且处理方式也简单粗暴,直接返回传入的对象。。。下面我们看看GsonConverterFactory内部是不是复杂些。这是我们最经常使用的一个内容转换器工厂,将javaBean数据转换为JSON数据格式的String数据。

GsonConverterFactory.class

public final class GsonConverterFactory extends Converter.Factory
GsonConverterFactory()@GsonConverterFactory.class
private final Gson gson; //操作实体private GsonConverterFactory(Gson gson) {    if (gson == null) throw new NullPointerException("gson == null");    this.gson = gson;}public static GsonConverterFactory create() { return create(new Gson()); }public static GsonConverterFactory create(Gson gson) {  return new GsonConverterFactory(gson); }
responseBodyConverter()@GsonConverterFactory.class
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {     TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type)); //note1    return new GsonResponseBodyConverter<>(gson, adapter);}
1、对于type值我们之前已经讲过了,如果方法返回对象为Observable<Response<T>>,这里的type对应Response<T>;com.google.gson.reflect.TypeToken会对Response<T>进行分离得到Response和T;然后获取一个预期类型的适配器。创建一个GsonResponseBodyConverter对象
 requestBodyConverter()@GsonConverterFactory.class
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {     TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type)); //note1    return new GsonRequestBodyConverter<>(gson, adapter);}
1、大体上跟之前的responseBodyConverter一样,也是先得到一个预期类型的适配器,只是这里创建了一个GsonRequestBodyConverter对象
下面我们分别看看GsonResponseBodyConverter和GsonRequestBodyConverter的convert方法。

GsonResponseBodyConverter.class

final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {  private final Gson gson;  private final TypeAdapter<T> adapter;  GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {    this.gson = gson;    this.adapter = adapter;  }  @Override public T convert(ResponseBody value) throws IOException {    JsonReader jsonReader = gson.newJsonReader(value.charStream()); //note1    try {  return adapter.read(jsonReader); } //note2    finally { value.close(); }   }}
1、将待转换的ResponseBody数据以字符char的方式读取
2、利用构造GsonResponseBodyConverter对象时传入的TypeAdapter将ResponseBody的字符流转换成T对象

GsonRequestBodyConverter.class

final class GsonRequestBodyConverter<T> implements Converter<T, RequestBody> {  private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");  private static final Charset UTF_8 = Charset.forName("UTF-8");  private final Gson gson;  private final TypeAdapter<T> adapter;  GsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {    this.gson = gson;    this.adapter = adapter;  }  @Override public RequestBody convert(T value) throws IOException {    Buffer buffer = new Buffer(); //note1    Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8); //note2    JsonWriter jsonWriter = gson.newJsonWriter(writer);    adapter.write(jsonWriter, value); //note3    jsonWriter.close();    return RequestBody.create(MEDIA_TYPE, buffer.readByteString());//note4  }}
1、创建一个okio.Buffer对象
2、以UTF_8编码方式向buffer中写入数据
3、将传入T类型的数据进行JSON转换,并以UTF_8编码方式写入buffer
4、buffer以比特形式读取,写入RequestBody中,同时对应的MediaType为"application/json; charset=UTF-8"

    以上是对GsonConverterFactory的简单介绍,因为具体的转换是Gson的事情,涉及到json的格式细节问题,已经不是Retrofit的内容了,因此不再往下深入,如有兴趣可以看另一篇博客《 Json FastJson Gson介绍与使用》。GsonConverterFactory只重写了requestBodyConverter()和responseBodyConverter()两个方法,并没有重写stringConverter()方法。因为对于String类型的转换已经被BuildInConverters拦截了,因此GsonConverterFactory不再需要对String类型进行转换。这里需要注意的是requestBodyConverter()和responseBodyConverter()两个方法可以说对于任何参数来者不拒,它绝对不会返回null,它不对传入该方法的Type type, Annotation[] annotations数据进行任何判断。因此Retrofit作者——jake-wharton大神强调一定将GsonConverterFactory添加到Retrofit的ArrayList<Converter.Factory>集合的末尾。

附录

还记得在parseResponse()@OkHttpCall.class中对有如下一段代码
Response<T> parseResponse(okhttp3.Response rawResponse) {    ....    int code = rawResponse.code();    if (code < 200 || code >= 300) { //响应执行失败     ResponseBody bufferedBody = Utils.buffer(rawBody);     return Response.error(bufferedBody, rawResponse);    }    if (code == 204 || code == 205) { //响应执行成功 但是没有返回数据body为空      return Response.success(null, rawResponse);    } ....}
方法中对网络的状态码进行了判断,但是很多童鞋可能不太通这些状态码的含义,特此从网上趴下来一些常用的状态码附录在此,方便学习。
Http状态码:
  • 成功(2字头)
    • 200 OK:请求成功、其后是对GET和POST请求的应答文档
    • 202 Accepted:供处理的请求已被接受,但是处理未完成。
    • 204 No Content:没有新文档。浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的。
    • 205 Reset Content:没有新文档。但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容。
    • 206 Partial Content:断点续传,客户发送了一个带有Range头的GET请求,服务器完成了它。
  • 重定向(3字头)
    • 300 Multiple Choices:多重选择。链接列表。用户可以选择某链接到达目的地。最多允许五个地址。
    • 301 Moved Permanently:所请求的页面已经转移至新的url。
    • 302 Move temporarily:所请求的页面临时转移至新的url。如果这不是一个 GET 或者 HEAD 请求,那么浏览器禁止自动进行重定向,除非得到用户的确认
    • 304 Not Modified:客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。
  • 请求错误(4字头)
    • 400 Bad Request:语义有误、请求参数有误。
    • 403 Forbidden:服务器已经理解请求,但是拒绝执行它。
    • 404 Not Found:请求失败,请求所希望得到的资源未被在服务器上发现
  • 服务器错误(5、6字头)
    • 500 Internal Server Error:请求未完成。服务器遇到不可预知的情况。
更多状态码参考:w3school http://www.w3school.com.cn/tags/html_ref_httpmessages.asp


0 0
原创粉丝点击