如何制作RxErrorHandlingCallAdapterFactory? [英] How to make RxErrorHandlingCallAdapterFactory?

查看:253
本文介绍了如何制作RxErrorHandlingCallAdapterFactory?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了

但是在新版本中编译'com.squareup.retrofit2:adapter-rxjava:2.2.0'在CallAdapter处有两个参数
CallAdapter<?,?>

But in new ver compile 'com.squareup.retrofit2:adapter-rxjava:2.2.0' at CallAdapter it has two params CallAdapter<?,?>

如何修改 RxCallAdapterWrapper 实现,如果来自 CallAdapter<?,?>

How to modify RxCallAdapterWrapper to implement if from CallAdapter<?,?>

推荐答案

免责声明:我是您引用的博客文章的作者

原始帖子旨在证明概念和RxJava 2,因此我也更容易用该版本进行解释,但我将尝试涵盖更多领域。我猜您正在使用版本1,因为您谈论的是 adapter-rxjava 而不是 adapter-rxjava2 。也就是说,版本1的实现应该非常简单,只需使用正确的导入即可。

The original post was meant as a proof of concept and for RxJava 2 so it's easier for me to explain with that version too, but I'll try and cover more ground. I'm guessing you're using version 1, since you talk about adapter-rxjava and not adapter-rxjava2. That said, the implementation for version 1 should be pretty straight forward and just a matter of using the right imports.

这是我使用RxJava 2完成的工作:

Here's what I've done using RxJava 2:

class RxErrorHandlingCallAdapterFactory extends CallAdapter.Factory {
  private final RxJava2CallAdapterFactory original;

  private RxErrorHandlingCallAdapterFactory() {
    original = RxJava2CallAdapterFactory.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<R> implements CallAdapter<R, Object> {
    private final Retrofit retrofit;
    private final CallAdapter<R, Object> wrapped;

    public RxCallAdapterWrapper(Retrofit retrofit, CallAdapter<R, Object> wrapped) {
        this.retrofit = retrofit;
        this.wrapped = wrapped;
    }

    @Override
    public Type responseType() {
        return wrapped.responseType();
    }

    @Override
    public Object adapt(Call<R> call) {
        Object result = wrapped.adapt(call);
        if (result instanceof Single) {
            return ((Single) result).onErrorResumeNext(new Function<Throwable, SingleSource>() {
                @Override
                public SingleSource apply(@NonNull Throwable throwable) throws Exception {
                    return Single.error(asRetrofitException(throwable));
                }
            });
        }
        if (result instanceof Observable) {
            return ((Observable) result).onErrorResumeNext(new Function<Throwable, ObservableSource>() {
                @Override
                public ObservableSource apply(@NonNull Throwable throwable) throws Exception {
                    return Observable.error(asRetrofitException(throwable));
                }
            });
        }

        if (result instanceof Completable) {
            return ((Completable) result).onErrorResumeNext(new Function<Throwable, CompletableSource>() {
                @Override
                public CompletableSource apply(@NonNull Throwable throwable) throws Exception {
                    return Completable.error(asRetrofitException(throwable));
                }
            });
        }

        return result;
    }

    private RetrofitException asRetrofitException(Throwable throwable) {
        // We had non-200 http error
        if (throwable instanceof HttpException) {
            HttpException httpException = (HttpException) throwable;
            Response response = httpException.response();
            return RetrofitException.httpError(response.raw().request().url().toString(), response, retrofit);
        }
        // A network error happened
        if (throwable instanceof IOException) {
            return RetrofitException.networkError((IOException) throwable);
        }

        // We don't know what happened. We need to simply convert to an unknown error

        return RetrofitException.unexpectedError(throwable);
    }
  }
}

没有重大变化,只是一些玩弄返回类型。现在,如果您查看 RxJava2CallAdapter ,它实现了 CallAdapter< R,Object> ,因此我们需要对此进行说明。

No major changes, just some playing around with return types. Now if you look at the RxJava2CallAdapter it implements CallAdapter<R, Object>, so we need to account for this.

然后,我为实例类型添加了一些检查,以确保我们返回的是正确的东西。

Then I've added some checks for the instance types to make sure we're returning the right things.

真正重要的部分是确保您导入正确的软件包。改装适配器检查特定的类别。我遇到的一个问题是导入错误,并且遇到了以下情况:我正在检查 Throwable 是否是 com.jakewharton.retrofit2.adapter的实例。 HttpException ,尽管它实际上是 retrofit2.adapter.rxjava2.HttpException 的实例。

The really important part is to make sure you import the right packages. Retrofit adapters check for specific classes. One problem I had was having the wrong imports and had situations where I was checking if the Throwable was an instance of com.jakewharton.retrofit2.adapter.HttpException, while it was actually an instance of retrofit2.adapter.rxjava2.HttpException.

希望这会有所帮助

这篇关于如何制作RxErrorHandlingCallAdapterFactory?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆