注意:以下分析都是基于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 extends Runnable> 到 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, 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默认网络请求适配器ExecutorCallAdapterFactory 和RxJavaCallAdapterFactory 进行介绍,随后介绍Retrofit的默认内容转换器BuiltInConverters 和GsonConverterFactory 。在此需要在此强调的是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@Ex ecutorCallAdapterFactory.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 + " extends Foo>");
}
if (isCompletable) {
return CompletableHelper.createCallAdapter(scheduler);
}
CallAdapter> 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()@Rx JavaCallAdapterFactory.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 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 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的转变;
2、Response 到 Response的转变;
3、Response 到 T 的转变;
4、Observable> 创建一个ResponseCallAdapter对象
5、Observable>创建一个ResultCallAdapter对象
6、默认创建一个 SimpleCallAdapter对象,先对该对象进行介绍
SimpleCallAdapter.class@Rx JavaCallAdapterFactory.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@Rx Java CallAdapterFactory.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 super Response> 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 super Response> 类型
2、利用OkHttpCall和Subscriber super Response>创建一个事件生成对象
3、一般该方法的结果就是调用requestArbiter.request(Integer.MAX_VALUE);所以我们接下来看看RequestArbiter类的request方法是如何定义的。
RequestArbiter.class@Rx Java CallAdapterFactory.class
static final class RequestArbiter extends AtomicBoolean implements Subscription, Producer {
private final Call call; //构造该对象时传入的OkHttpCall
private final Subscriber super Response> subscriber; //构造该对象时传入的Subscriber super Response>
RequestArbiter(Call call, Subscriber super Response> 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 super Response>的onNext方法处理上面得到的Response对象
3、如果当前subscribe没有解绑,调用Subscriber super Response>的onError方法处理异常t
4、如果当前subscribe没有解绑,调用Subscriber super Response>的onCompleted()方法
5、如果当前subscribe要求解绑,调用OkHttpCall的cancel()方法断开连接
6、判断一个subscribe是否解绑,实则是判断OkHttpCall是否断开连接
发现没,如果使用Observable进行网络访问,那么一旦Subscribe解除绑定就会断开网络连接,而且不再接收任何网络信息 ,这也是为什么Retrofit作者建议在Activity和Fragment中使用Retrofit+RxJava时一定要在onDestiny方法中调用subscription.unsubscribe()方法解除绑定的原因,即断开网络连接,回收网络资源。
到此为止我们分析完了[email protected] 的note1,得到的Observable 能接收Subscriber super Response>类型的订阅者。接着我们继续分析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 super Response> call(final Subscriber super T> 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 super T> 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@Rx JavaCallAdapterFactory.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@Rx JavaCallAdapterFactory.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, 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 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, 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;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方法
static final class StreamingResponseBodyConverter implements Converter {
static final StreamingResponseBodyConverter INSTANCE = new StreamingResponseBodyConverter();
@Override public ResponseBody convert(ResponseBody value) throws IOException {
return value;
}
}
直接返回传入的ResponseBody类型数据。
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,该对象已经将数据全部读取到了内存中。
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, 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 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类型进行转换。这里需要注意的是requestBod yConverter()和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