gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-28 23:32:31 31 4
gpt4 key购买 nike

我是 RxJava 新手,如果这听起来太新手,请原谅我 :-)。

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

例如:对于来 self 的服务器的特定错误代码,我在响应正文中收到一个新的 Auth token ,刷新该 token ,然后 clone.enqueue 调用。当然,我的服务器的响应还有其他几种全局行为。

当前解决方案(无 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();
}

我的问题是:有没有办法在最终链接(或重试)回订阅者方法之前进行这种集中式响应处理行为?

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

Forcing request retry after custom API exceptions in RxJava

Retrofit 2 and RxJava error handling operators

最佳答案

您提供的两个链接是一个非常好的起点,我用来构建解决方案以应对意外

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

我已经重写了 CallAdapter.Factory 来处理错误并对它们做出适当的 react 。

  1. solution 导入 RetryWithDelayIf你找到了

  2. 重写 CallAdapter.Factory 来处理错误:

    public class RxCallAdapterFactoryWithErrorHandling extends CallAdapter.Factory {
    private final RxJavaCallAdapterFactory original;

    public RxCallAdapterFactoryWithErrorHandling() {
    original = RxJavaCallAdapterFactory.create();
    }

    @Override
    public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    return new RxCallAdapterWrapper(retrofit, original.get(returnType, annotations, retrofit));
    }

    public 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(final Call<R> call) {
    return ((Observable) wrapped.adapt(call)).onErrorResumeNext(new Func1<Throwable, Observable>() {
    @Override
    public Observable call(Throwable throwable) {
    Throwable returnThrowable = throwable;
    if (throwable instanceof HttpException) {
    HttpException httpException = (HttpException) throwable;
    returnThrowable = httpException;
    int responseCode = httpException.response().code();
    if (NetworkUtils.isClientError(responseCode)) {
    returnThrowable = new HttpClientException(throwable);
    }
    if (NetworkUtils.isServerError(responseCode)) {
    returnThrowable = new HttpServerException(throwable);
    }
    }

    if (throwable instanceof UnknownHostException) {
    returnThrowable = throwable;
    }

    return Observable.error(returnThrowable);
    }
    }).retryWhen(new RetryWithDelayIf(3, DateUtils.SECOND_IN_MILLIS, new Func1<Throwable, Boolean>() {
    @Override
    public Boolean call(Throwable throwable) {
    return throwable instanceof HttpServerException
    || throwable instanceof SocketTimeoutException
    || throwable instanceof UnknownHostException;
    }
    }));
    }
    }
    }

    HttpServerException 只是一个自定义异常。

  3. Retrofit.Builder 中使用它

    Retrofit retrofit = new Retrofit.Builder()
    .addCallAdapterFactory(new RxCallAdapterFactoryWithErrorHandling())
    .build();

Extra:如果您希望解析来自 API 的错误(不调用 UnknownHostExceptionHttpException 的错误MalformedJsonException 等)您需要覆盖 Factory并在构建 Retrofit 实例期间使用自定义。解析响应并检查它是否包含错误。如果是,则抛出错误,错误将在上述方法内部进行处理。

关于android - RxJava + Retrofit -> BaseObservable 用于 API 调用,用于集中响应处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39437299/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com