Retrofit网络异常回调中拿到网络请求url等数据

前言

开心原创哦

Retrofit 与RxJava结合,异常 处理都走了onError(Throwable t) 方法.  在该异常回调中,我们拿不到网络请求url等数据,只能拿到Throwable对象。

使用场景

异常统一处理,但异常回调中无法区分哪一个接口网络请求出现异常了。例如一个界面有多个接口,其中某个接口请求出现异常了,在异常统一处理里面无法区分。(使用场景):界面A有  下拉刷新和 上拉加载的接口, 同时还有点赞 、关注接口,当在上拉加载更多过程中,点赞接口触发,若某一接口请求失败,无法区分是上拉加载出现异常,还是点赞失败,这对于处理对应的UI是无法完成的。

解决方法一: 在不同接口里面传入对应的new Action, 这 样每个接口单独处理 自己的异常回调

解决方法二: 在异常处理的回调中拿到对应接口的数据,如url等,这样就可以区分是哪个接口网络请求异常了。

方法一大家一般都知道如何使用,我就不作累述了。

在Rxjava 的onError回调中拿到网络请求的URL等数据

在创建Retrofit对象时,会传入CallAdapter.Factory 对象,该对象是专门处理回调的。包括成功、失败回调。

如下: 

new Retrofit.Builder().addCallAdapterFactory(RxJavaCallAdapterFactory.create());

因为使用Rxjava与Retrofit结合,所以这里添加回调是使用RxJavaCallAdapterFactory创建的。

由于每一个版本的Retrofit的源码都略有不一样,但原理相同,大家可以根据我的思路去解决。我司的项目依赖的2.1.0版本

    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

查看了RxJavaCallAdapterFactory的源码,Retrofit与Rxjava结合使用时,回调处理都交给了这个库来作处理,将Retrofit抛出的异常给Rxjava的onError回调,将请求成功给onNext和onComplete

'com.squareup.retrofit2:adapter-rxjava:2.1.0

通过debug可以发现所有回调最后都走了RxJavaCallAdapterFactory 里面的这个方法。

 @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();
        if (!subscriber.isUnsubscribed()) {
          subscriber.onNext(response);
        }
      } catch (Throwable t) {
        Exceptions.throwIfFatal(t);
        if (!subscriber.isUnsubscribed()) {
//          MyNetThrowable myNetThrowable = new MyNetThrowable(t, call);
          subscriber.onError(t);
        }
        return;
      }

      if (!subscriber.isUnsubscribed()) {
        subscriber.onCompleted();
      }
    }

为了在onError回调中拿到网络url等数据,在这里我们可以 自定义一个Throwable,然后将网络的Call对象放进去,这样通过Call对象就可以 拿到请求url, host,headers,请求参数等数据了。

自主 义Throwable对象 MyNetThrowable,如下:

public class MyNetThrowable extends Throwable {

    public final Call call;

    public MyNetThrowable(Throwable e, Call call) {
        super(e);
        this.call = call;
    }

    public Call getCall() {
        return call;
    }
}

然后修改RxJavaCallAdapterFactory的源码 即可。请注意上面注释的那一行代码,

if (!subscriber.isUnsubscribed()) {
          MyNetThrowable myNetThrowable = new MyNetThrowable(t, call);
          subscriber.onError(myNetThrowable);
        }

这样既可以拿到之前的Throwable对象,也可以拿到请求Call对象

使用:

在onError回调方法中,mError是给Rxjava的onError回调使用的,所有网络请求异常都会走这里。

  protected final Action1 mError = t -> {
        if (t instanceof MyNetThrowable) {
            MyNetThrowable t1 = (MyNetThrowable) t;
            Call call = t1.call;
            Request request = call.request();
            Headers headers = request.headers();
            HttpUrl url = request.url();
            URL url1 = url.url();

        }
}

这样就可以知道哪一个接口网络请求出现异常了。

延伸

如何修改RxJavaCallAdapterFactory源码,如何自定义CallAdapterFactory、

查看其源码可以发现RxJavaCallAdapterFactory是 不允许你对其自定义的,需要修改其源码打成jar包重新依赖。

备注: 2.1.0版本的是这个情况,现最新版本已经更新了,RxJavaCallAdapterFactory 的源码也更改颇多,但原理没变,大家可以关注一下最新版本。

先从retrofit 的github网址上下载对应版本号的源码,然后做成android lib ,修改完成后打成aar包,将aar包中jar包复制出来放入项目的lib文件夹即可(该lib除了代码没有其它资源,直接复制其jar包即可了,依赖也方便),不再使用如下方式依赖了。

compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

如下图

Retrofit网络异常回调中拿到网络请求url等数据_第1张图片

你可能感兴趣的:(andriod)