RxJava + Retrofit - > BaseObservable用于集中响应处理的API调用

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (70)

截至目前,我有一个抽象的CallbackClass实现Retofit回调。在那里,我捕获了回调的“onResponse”和“onError”方法,并在最终转发到自定义实现的方法之前处理各种错误类型。我也使用这个集中的类来请求/响应应用程序日志和其他东西。

例如:对于来自服务器的特定错误代码,我会在响应正文中接收一个新的身份验证令牌,刷新该令牌,然后克隆该请求。当然,还有其他一些全球行为来自我的服务器的响应。

当前解决方案(不含Rx):

    public abstract void onResponse(Call<T> call, Response<T> response, boolean isSuccess);

    public abstract void onFailure(Call<T> call, Response<T> response, Throwable t, boolean isTimeout);

    @Override
    public void onResponse(Call<T> call, Response<T> response) {
        if (_isCanceled) return;

        if (response != null && !response.isSuccessful()) {
            if (response.code() == "SomeCode" && retryCount < RETRY_LIMIT) {
                TokenResponseModel newToken = null;
                try {
                    newToken = new Gson().fromJson(new String(response.errorBody().bytes(), "UTF-8"), TokenResponseModel.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                    SomeClass.token = newToken.token;
                    retryCount++;
                    call.clone().enqueue(this);
                    return;
                }
            }
        } else {
            onResponse(call, response, true);
            removeFinishedRequest();
            return;
        }

        onFailure(call, response, null, false);
        removeFinishedRequest();
    }

    @Override
    public void onFailure(Call<T> call, Throwable t) {
        if (_isCanceled) return;

        if (t instanceof UnknownHostException)
            if (eventBus != null)
                eventBus.post(new NoConnectionErrorEvent());

        onFailure(call, null, t, false);
        removeFinishedRequest();
    }

我的问题是:在最终链接(或重试)回订阅者方法之前,是否有任何方法可以实现这种集中响应处理行为?

我发现这两个链接都有一个很好的起点,但不是具体的解决方案。任何帮助将非常感激。

提问于
用户回答回答于

您提供的两个链接是一个很好的起点,我用它来构造解决方案来应对意外事件。

  • 有时由于暂时缺乏网络连接或切换到低吞吐量网络标准(如EDGE),有时会发生网络错误,从而导致SocketTimeoutException。
  • 服务器错误->有时由于服务器超载而发生

我已经超越了CallAdapter.Factory处理错误并对错误作出适当反应。

  1. 进口RetryWithDelayIf你发现
  2. 覆盖CallAdapter.Factory要处理错误: 公共类RxCallAdapterFactoryWithErrorHandling扩展CallAdapter。工厂{私有最终的RxJavaCallAdapterFactory原件;公共的RxCallAdapterFactoryWithErrorHandling(){原件=RxJavaCallAdapterFactory.create();}@overoverpublic CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) { return new RxCallAdapterWrapper(retrofit, original.get(returnType, annotations, retrofit)); } public class RxCallAdapterWrapper implements CallAdapter<Observable<?>>{私有最终改造;私有最终呼叫适配器<?> wrapped; public RxCallAdapterWrapper(Retrofit retrofit, CallAdapter<?>{这个。改造=改造;这。包装=包装;}@覆盖公共类型响应类型(){返回包装。ResponseType();}@Suppress Warnings(“未检查”)@Overoverpublic<R>可观察的<?>适应(最终呼叫)<R>调用){Ref((可观察)Wrapped.适应性(Call)).onErrorResumeNext(新功能1<Throwable,观测>>(){@覆盖公共可观察调用(Throwable Throwable){Throwable ReportnThrowable=throwable;if(Throwable Instanceof HttpException){HttpException=(HttpException)throwable;Recnthrowable=httpException;int responseCode=httpException)。响应().code();if(NetworkUtils)。isClientError(ResponseCode)){back nThrowable=newHttpClientException(Throwable);}if(NetworkUtils)。isServerError(ResponseCode){back nThrowable=newHttpServerException(Throwable);}}if(不明未知的不稳定祖先){back nThrowable=throwable;}返回观察者.Error(返回nThrowable);}}。重新开始时(新的重则延迟(3,DateUtils)。第二[医]在[医]Millis,新功能1<Throwable,boole>(){@覆盖公共布尔调用(Throwable Throwable){返回HttpServerException的Throwable实例--SocketTimeoutException的可抛实例;});}}HttpServerException只是一个定制的例外。
  3. 用在Retrofit.Builder改造改造=新改造。建筑商()。addCallAdapterFactory(新的RxCallAdapterFactoryWithErrorHandling())。建造();

额外::如果您希望解析来自API的错误(不调用的错误)UnknownHostException,,,HttpExceptionMalformedJsonException(等等)你需要覆盖Factory在建筑过程中使用定制的Retrofit举个例子。解析响应并检查它是否包含错误。如果是,则抛出错误和错误将在上述方法中处理。

用户回答回答于

你有没有考虑使用rxjava适配器进行改造? 在您的Gradle文件中添加https://mvnrepository.com/artifact/com.squareup.retrofit2/adapter-rxjava/2.1.0

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

这里是改造的界面

public interface Service {
@GET("userauth/login?")
Observable<LoginResponse> getLogin(
        @Query("v") String version,
        @Query("username") String username,
        @Query("password") String password);
}

这是我的实现

Service.getLogin(
            VERSION,
            "username",
            "password")
            .subscribe(new Subscriber<LoginResponse>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(LoginResponse loginResponse) {

                }
            });

请注意我正在使用gson转换器工厂来解析我的响应,以便返回pojo(Plain Ole Java对象)。

扫码关注云+社区