Rxjava+retrofit+okhttp的网络请求框架
之需要注意的地方
1 retrofit和okhttp异步回调的线程问题:
- okhttp异步调用后,callback运行在子线程
- retrofit异步调用后,其callback运行在主线程,retrofit就是对okhttp的一系列封装,运用了大量设计模式,其回调结果最后通过handle传到了主线程,这点要注意,尤其在更新ui时
- rxjava封装后,回调线程可以通过其线程调度来很方便的设置
2 rxjava 的Observable封装的 retrofit call的泛型参数:
-
TypeBody(class类):如public class Result{ private String name; private String ID; } //在相应retrofit接口中 @GET(.....) Observable<Result> Login()通过添加gson转换器,将网络请求响应中返回的json转换为相应的java类,方便操作,注意这个必须在创建retrofit是添加gson转换器
.addConverterFactory(GsonConverterFactory.create()) -
ResponseBody(okhttp包下的)@GET(...) Observable<ResponseBody> Login()这个适用于你不需要将其转换成具体的类,只是想获取响应体,当让你也可以获取body后自己手动解析body数据
-
Response<T>(retrofit包下)这个将所有响应结果都封装到了这个response里,他的泛型参数可以填ResponseBody或者class类,通过他不仅可以获取body,还可以获取响应码等。
3 Rxjava的网络请求错误处理
- 注意,如果是用Response包裹的响应体,那么之前说过,所有东西都被包裹在了Response里,所以即使是错误的响应,如4××/5××,也会包裹在Response里,发送给
onNext(),而不会发送给onError(),而错误的响应体可以通过获取错误的响应体。 而如果不是用Response包裹,那么除了2**的响应吗会进入if (e instanceof HttpException){ (HttpException)e).response().errorBody() }onNext()里,其他的响应码都会直接进入onError()里,这样就中断了这个观察链
参考stackoverfollow
- 关于rxjava的flatmap链式调用:flatmap可以解决回调地狱,解决连续进行网络请求的问题,如
第一个flatmap中抛出了一个异常,那么下一个flatmap就不会调用,直接进入了最后订阅的观察者中,进入Observable.just("hello") .flatMap(new Func1<String, Observable<?>>() { @Override public Observable<?> call(String s) { Log.i(TAG, "call: flatmap -----1"); s = "hellp flapmap1"; if (s != null) return Observable.error(new NullPointerException("null test")); return Observable.just(s); } }).flatMap(new Func1<Object, Observable<?>>() { @Override public Observable<?> call(Object o) { Log.i(TAG, "call: flatmap-----2"); return Observable.just("33333"); } }).subscribe(new Subscriber<Object>() { @Override public void onCompleted() { Log.i(TAG, "onCompleted: "); } @Override public void onError(Throwable e) { Log.i(TAG, "onError: call"); if (e instanceof NullPointerException) Log.i(TAG, "onError: illegal " + e.getMessage()); } @Override public void onNext(Object o) { Log.i(TAG, "onNext: "); } });onError()里。可见,即便你在flatmap里对上一个被观察者发送的结果进行了操作,但他并不算是一个观察者,只是对其进行了一部分处理,map等操作符也是这样,他们共同组成了一个长长的链,唯一的观察者在最后订阅的Subscriber中处理,所以如果中间任意环节出了异常,那么该链在此中断,直接进入最后观察者的onerror里。
所以之前的如果用Response包裹,就不会中断观察链,你可以根据响应码做一些处理。
4 okhttp的拦截器及重定向处理
- okhttp的拦截器是其责任链模式的重要实现,通过一个个拦截器将网络链接的各个部分,模块拆分开,分工明确
- okhttp中对重定向的处理是通过其第一个内置的拦截器
RetryAndFollowUpInterceptor实现的,他通过while循环来不断创建request请求资源,知道响应码为200(或错误),当然他也负责进行失败重试 - 关于Application interceptors与Network Interceptors区别 他们其实都是用户自定义的拦截器,只是添加顺序不同,导致有区别 okhttp源码中的添加顺序: