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默认网络请求适配器ExecutorCallAdapterFactory和RxJavaCallAdapterFactory进行介绍,随后介绍Retrofit的默认内容转换器BuiltInConverters和GsonConverterFactory。在此需要在此强调的是Retrofit的ArrayList<CallAdapter.Factory> adapterFactories集合中ExecutorCallAdapterFactory位于该集合的末尾。Retrofit的ArrayList<Converter.Factory> converterFactories集合中BuiltInConverters位于该集合的首位。在接口方法Method向ServiceMethod的转化过程中,都是从adapterFactories和converterFactories集合的首位开始往后找的,因此集合中的工厂位置越靠前就拥有越高的使用权限,因为GsonConverterFactory它能对任何数据都可以进行转换(最多转换异常嘛),因此Retrofit作者特别强调一定将GsonConverterFactory添加到Retrofit的converterFactories集合的末尾。
ExecutorCallAdapterFactory.class
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
- Retrofit的使用与深入学习(下)
- Retrofit的使用与深入学习(上)
- Retrofit的学习与资料
- RxAndroid 与 Retrofit的使用
- Retrofit的详解与使用(多文件上传)
- Retrofit的使用与基本的封装
- 使用MVP+Retrofit+RxJava实现的的Android Demo (下)使用Retrofit+RxJava处理网络请求
- RxJava 与 Retrofit 参考学习的资料
- RxJava的使用与深入学习
- EventBus的使用与深入学习
- EventBus的使用与深入学习
- EventBus的使用与深入学习
- EventBus的使用与深入学习
- EventBus的使用与深入学习
- RxJava的使用与深入学习
- RxJava的使用与深入学习
- RxJava的使用与深入学习
- Retrofit的使用(1)
- iOS、mac开源项目及库汇总
- 同一类型标识符(Uniform Type Identifier,UTI)
- Fragment中startActivityForResult与onActivityResult详细解决方案
- how a call be dailed out(Android Telephony basing on M)
- Android四大组件之Service
- Retrofit的使用与深入学习(下)
- Java中int转String 和 String转int 各方法效率对比
- Linux-16、17、18-服务器操作系统CentOS6.5安装实战(L003-30,31,32)
- Swift学习笔记二:常用类型的注意事项
- Android http操作
- INT BYTE4
- Block的使用
- Ubuntu下Spark开发环境搭建
- java获取当前类的绝对路径