Rxjava+retrofit+okhttp的网络请求框架
之需要注意的地方
1 retrofit和okhttp异步回调的线程问题:
- okhttp异步调用后,callback运行在子线程
- retrofit异步调用后,其callback运行在主线程,retrofit就是对okhttp的一系列封装,运用了大量设计模式,其回调结果最后通过handle传到了主线程,这点要注意,尤其在更新ui时
- rxjava封装后,回调线程可以通过其线程调度来很方便的设置
2 rxjava 的Observable封装的 retrofit call的泛型参数:
TypeBody(class类)
:如1
2
3
4
5
6
7
8
9public class Result{
private String name;
private String ID;
}
//在相应retrofit接口中
@GET(.....)
Observable<Result> Login()通过添加gson转换器,将网络请求响应中返回的json转换为相应的java类,方便操作,注意这个必须在创建retrofit是添加gson转换器
.addConverterFactory(GsonConverterFactory.create())
ResponseBody
(okhttp包下的)1
2@GET(...)
Observable<ResponseBody> Login()这个适用于你不需要将其转换成具体的类,只是想获取响应体,当让你也可以获取body后自己手动解析body数据
Response<T>(retrofit包下)
这个将所有响应结果都封装到了这个response里,他的泛型参数可以填ResponseBody或者class类,通过他不仅可以获取body,还可以获取响应码等。
3 Rxjava的网络请求错误处理
- 注意,如果是用Response包裹的响应体,那么之前说过,所有东西都被包裹在了Response里,所以即使是错误的响应,如4××/5××,也会包裹在Response里,发送给
onNext()
,而不会发送给onError()
,而错误的响应体可以通过获取错误的响应体。1
2
3if (e instanceof HttpException){
(HttpException)e).response().errorBody()
}
而如果不是用Response包裹,那么除了2**的响应吗会进入onNext()
里,其他的响应码都会直接进入onError()
里,这样就中断了这个观察链
参考stackoverfollow
- 关于rxjava的flatmap链式调用:flatmap可以解决回调地狱,解决连续进行网络请求的问题,如第一个flatmap中抛出了一个异常,那么下一个flatmap就不会调用,直接进入了最后订阅的观察者中,进入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39Observable.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源码中的添加顺序:
可见Application interceptors第一个添加,而Network Interceptors添加在RetryAndFollowUpInterceptor等拦截器之后,所以Network Interceptors可以拦截到重定向的请求,而Application interceptors只能拦截到刚开始的请求和最后重定向后的结果