Android 网络请求心得

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
    9
    public 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
    3
    if (e instanceof HttpException){
    (HttpException)e).response().errorBody()
    }
    获取错误的响应体。
    而如果不是用Response包裹,那么除了2**的响应吗会进入onNext()里,其他的响应码都会直接进入onError()里,这样就中断了这个观察链

picture_1

参考stackoverfollow

  • 关于rxjava的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
    39
    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: ");
    }
    });
    第一个flatmap中抛出了一个异常,那么下一个flatmap就不会调用,直接进入了最后订阅的观察者中,进入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只能拦截到刚开始的请求和最后重定向后的结果
    拦截器调用示意图

参考:博客

,
© 2020 WPY's Android Tour All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero