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


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

    本节是《Retrofit的使用与深入学习》的进阶版本,着重讲解一下Retrofit中的Converter.Factory和CallAdapter.Factory两个对象。正式介绍之前,首先回顾一下这两个抽象类都定义了哪些方法:
public interface CallAdapter {
  Type responseType();   //该请求适配器返回的数据类型
   T adapt(Call call);  //该请求适配器对原始Call的再次封装,如Call到Observable,这里的Call在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 到  Runnable的转变;第i个参数的最上层的数据类型
    protected static Class getRawType(Type type) {  return Utils.getRawType(type); }
     //Example:完成List 到 List.class的转变;  即得到最外层的那个数据类型
  }
}

public interface Converter {
  T convert(F value) throws IOException;
  abstract class Factory {
    public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { return null; } //对响应数据的转换
    public Converter requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return null; } //对请求数据的转换
    public Converter stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) {  return null;  }  //String类型转换
  }
}
    本节我们将先对Retrofit默认网络请求适配器ExecutorCallAdapterFactoryRxJavaCallAdapterFactory进行介绍,随后介绍Retrofit的默认内容转换器BuiltInConvertersGsonConverterFactory。在此需要在此强调的是Retrofit的ArrayList adapterFactories集合中ExecutorCallAdapterFactory位于该集合的末尾。Retrofit的ArrayList 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>对象的get方法
get()@ExecutorCallAdapterFactory.class
public CallAdapter> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {  return null; } 
    final Type responseType = Utils.getCallResponseType(returnType);
    
    return new CallAdapter>() {
      @Override public Type responseType() { return responseType; } 
      @Override public  Call adapt(Call call) { return new ExecutorCallbackCall<>(callbackExecutor, call); } //note1
    };
  }
1、创建一个回调请求执行器,该执行器实现了Call接口
static final class ExecutorCallbackCall implements Call
ExecutorCallbackCall.class@ExecutorCallAdapterFactory.class
final Executor callbackExecutor; //回调方法执行器
final Call delegate;//网络请求实体
ExecutorCallbackCall(Executor callbackExecutor, Call delegate) {
      this.callbackExecutor = callbackExecutor;
      this.delegate = delegate;
}
@Override public boolean isExecuted() { return delegate.isExecuted(); }
@Override public Call clone() {  return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone()); }
@Override public Request request() { return delegate.request(); }

@Override public Response execute() throws IOException {  return delegate.execute(); } //note1
@Override public void enqueue(final Callback callback) {//note2
      if (callback == null) throw new NullPointerException("callback == null");
      delegate.enqueue(new Callback() {
        @Override public void onResponse(Call call, final Response 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 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对象基本透明,网络请求都是通过调用adapt传入参数Call对象的同名方法。

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

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

RequestArbiter.class@RxJavaCallAdapterFactory.class
static final class RequestArbiter extends AtomicBoolean implements Subscription, Producer {
    private final Call call; //构造该对象时传入的OkHttpCall
    private final Subscriber> subscriber; //构造该对象时传入的Subscriber>
    RequestArbiter(Call call, Subscriber> 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 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对象
2、如果当前subscribe没有解绑,调用Subscriber>的onNext方法处理上面得到的Response对象
3、如果当前subscribe没有解绑,调用Subscriber>的onError方法处理异常t
4、如果当前subscribe没有解绑,调用Subscriber>的onCompleted()方法
5、如果当前subscribe要求解绑,调用OkHttpCall的cancel()方法断开连接
6、判断一个subscribe是否解绑,实则是判断OkHttpCall是否断开连接
发现没,如果使用Observable进行网络访问,那么一旦Subscribe解除绑定就会断开网络连接,而且不再接收任何网络信息,这也是为什么Retrofit作者建议在Activity和Fragment中使用Retrofit+RxJava时一定要在onDestiny方法中调用subscription.unsubscribe()方法解除绑定的原因,即断开网络连接,回收网络资源。

到此为止我们分析完了[email protected]的note1,得到的Observable 能接收Subscriber>类型的订阅者。接着我们继续分析note2的.lift(OperatorMapResponseToBodyOrError.instance())操作。


OperatorMapResponseToBodyOrError.class

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

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


上面介绍完了网络请求适配器工厂——CallAdapter.Factory,接着我们来学习内容转换工厂——Converter.Factory;首先看看Retrofit的内置的内容转换工厂
回顾一下内容工厂都需要实现哪些方法:
public interface Converter {
  T convert(F value) throws IOException;
  abstract class Factory {
    public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { return null; } //对响应数据的转换
    public Converter requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return null; } //对请求数据的转换
    public Converter 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 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>,对应type为Response
该方法能够要求获取ResponseBody、Void类型的返回值进行处理,分别返回BufferingResponseBodyConverter、StreamingResponseBodyConverter、VoidResponseBodyConverter;如果不是ResponseBody类型或者Void类型则返回null交给下一个内容转换器工厂进行处理。
requestBodyConverter()@BuiltInConverters.class
public Converter 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;Utils.getRawType(type))得到Request
当请求报文的body类型为RequestBody时,该方法返回一个RequestBodyConverter对象。否则交给下一个内容转换器处理。
stringConverter()@BuiltInConverters.class
public Converter 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 [email protected]
static final class StreamingResponseBodyConverter  implements Converter { 
    static final StreamingResponseBodyConverter INSTANCE = new StreamingResponseBodyConverter();
    @Override public ResponseBody convert(ResponseBody value) throws IOException {
      return value;
    }
}
直接返回传入的ResponseBody类型数据。
BufferingResponseBodyConverter [email protected]
static final class BufferingResponseBodyConverter  implements Converter { 
    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 [email protected]
static final class VoidResponseBodyConverter implements Converter {
    static final VoidResponseBodyConverter INSTANCE = new VoidResponseBodyConverter();
    @Override public Void convert(ResponseBody value) throws IOException {
      value.close();
      return null;
    }
}
直接关闭ResponseBody,返回null
static final class RequestBodyConverter implements Converter {
    static final RequestBodyConverter INSTANCE = new RequestBodyConverter();
    @Override public RequestBody convert(RequestBody value) throws IOException {  return value;  } 
}
直接返回RequestBody类型数据
static final class StringConverter implements Converter {
    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 responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { 
    TypeAdapter adapter = gson.getAdapter(TypeToken.get(type)); //note1
    return new GsonResponseBodyConverter<>(gson, adapter);
}
1、对于type值我们之前已经讲过了,如果方法返回对象为Observable>,这里的type对应Response;com.google.gson.reflect.TypeToken会对Response进行分离得到Response和T;然后获取一个预期类型的适配器。创建一个GsonResponseBodyConverter对象
 requestBodyConverter()@GsonConverterFactory.class
public Converter 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 implements Converter {
  private final Gson gson;
  private final TypeAdapter adapter;
  GsonResponseBodyConverter(Gson gson, TypeAdapter 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 implements Converter {
  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 adapter;
  GsonRequestBodyConverter(Gson gson, TypeAdapter 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集合的末尾。

附录

还记得在parseResponse()@OkHttpCall.class中对有如下一段代码
Response 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


你可能感兴趣的:(开源项目,Android技术,网络编程)