Retrofit2使用CallAdapterFactory的错误处理

来源:互联网 发布:linux用ubuntu 编辑:程序博客网 时间:2024/06/11 23:27

概述

在使用Retrofit1的时候有一个类叫ErrorHandler,可以方便的定义自己的异常处理,但是在Retrofit2中是没有这个类的,详情见讨论:How do we create ErrorHandler in retrofit 2.0? #1102

总结

在相关讨论之下发现了一种好的解决方案,详情见: Retrofit 2 and Rx Java call adapter error handling,主要通过CallAdapter.Factory 来实现,核心代码

  • 定义CallAdapter
public class RxErrorHandlingCallAdapterFactory extends CallAdapter.Factory {    private final RxJavaCallAdapterFactory original;    private RxErrorHandlingCallAdapterFactory() {        original = RxJavaCallAdapterFactory.create();    }    public static CallAdapter.Factory create() {        return new RxErrorHandlingCallAdapterFactory();    }    @Override    public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {        return new RxCallAdapterWrapper(retrofit, original.get(returnType, annotations, retrofit));    }    private static class RxCallAdapterWrapper implements CallAdapter<Observable<?>> {        private final Retrofit retrofit;        private final CallAdapter<?> wrapped;        public RxCallAdapterWrapper(Retrofit retrofit, CallAdapter<?> wrapped) {            this.retrofit = retrofit;            this.wrapped = wrapped;        }        @Override        public Type responseType() {            return wrapped.responseType();        }        @SuppressWarnings("unchecked")        @Override        public <R> Observable<?> adapt(Call<R> call) {            return ((Observable) wrapped.adapt(call)).onErrorResumeNext(new Func1<Throwable, Observable>() {                @Override                public Observable call(Throwable throwable) {                    return Observable.error(asRetrofitException(throwable));                }            });        }        private RetrofitException asRetrofitException(Throwable throwable) {            // We had non-200 http error            if (throwable instanceof HttpException) {            // A network error happened            }            if (throwable instanceof IOException) {            }            // We don't know what happened. We need to simply convert to an unknown error            return RetrofitException.unexpectedError(throwable);        }    }}
  • 定义Exception
public class RetrofitException extends RuntimeException {    public static RetrofitException httpError(String url, Response response, Retrofit retrofit) {        String message = response.code() + " " + response.message();        return new RetrofitException(message, url, response, Kind.HTTP, null, retrofit);    }    public static RetrofitException networkError(IOException exception) {        return new RetrofitException(exception.getMessage(), null, null, Kind.NETWORK, exception, null);    }    public static RetrofitException unexpectedError(Throwable exception) {        return new RetrofitException(exception.getMessage(), null, null, Kind.UNEXPECTED, exception, null);    }}
  • 设置到Builder
new Retrofit.Builder()        .baseUrl("your base url")        .addConverterFactory(GsonConverterFactory.create(new Gson()))        .addCallAdapterFactory(RxErrorHandlingCallAdapterFactory.create())        .build();
  • 错误处理
public void onError(Throwable throwable) {    if (throwable instanceof HttpException) {       // We had non-2XX http error    }    if (throwable instanceof IOException) {       // A network or conversion error happened    }    // We don't know what happened. We need to simply convert to an unknown error    // ...  }

相关代码整理: retrofit2

0 0