使用重试2改造的要求 [英] Retrying the request using Retrofit 2

查看:226
本文介绍了使用重试2改造的要求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何添加重试功能,通过改造2 库的要求。是这样的:

  service.listItems()排队(新回拨<名单,LT;项目>>(){
        @覆盖
        公共无效onResponse(响应<名单,LT;项目>>响应){
            ...
        }        @覆盖
        公共无效onFailure处(的Throwable t)的{
            ...
        }
    })retryOnFailure(5 / *倍* /);


解决方案

我终于做了这样的事情,有兴趣的人士:

1

首先我做了一个抽象类 CallbackWithRetry

 公共抽象类CallbackWithRetry< T>实现回调< T> {    私有静态最终诠释TOTAL_RETRIES = 3;
    私有静态最后弦乐TAG = CallbackWithRetry.class.getSimpleName();
    私人最终呼叫< T>呼叫;
    私人INT RetryCount重= 0;    公共CallbackWithRetry(呼叫< T>调用){
        this.call =调用;
    }    @覆盖
    公共无效onFailure处(的Throwable t)的{
        Log.e(TAG,t.getLocalizedMessage());
        如果(RetryCount重++< TOTAL_RETRIES){
            Log.v(TAG,重试...(+ RetryCount重+出的+ TOTAL_RETRIES +));
            重试();
        }
    }    私人无效重试(){
        。call.clone()排队(本);
    }
}

使用这个类,我可以做这样的事情:

  serviceCall.enqueue(新CallbackWithRetry<名单,LT;相册和GT;>(serviceCall){
    @覆盖
    公共无效onResponse(响应<名单,LT;相册和GT;>响应){
        ...
    }
});


2

这是不完全令人满意,因为我必须通过同样的 serviceCall 的两倍。这可以混淆为一个能想到的第二个 serviceCall (即进入的构造 CallbackWithRetry )应该或可以是不同的东西从第一个(我们调用它排队法)

所以,我实现了一个辅助类 CallUtils

 公共类CallUtils {    公共静态< T>无效enqueueWithRetry(呼叫< T>打电话,最后回调< T>回调){
        call.enqueue(新CallbackWithRetry< T>(通话){
            @覆盖
            公共无效onResponse(响应< T>响应){
                callback.onResponse(响应);
            }            @覆盖
            公共无效onFailure处(的Throwable t)的{
                super.onFailure(T);
                callback.onFailure(T);
            }
        });
    }}

我可以这样使用它:

  CallUtils.enqueueWithRetry(serviceCall,新的回调<名单,LT;相册和GT;>(){
    @覆盖
    公共无效onResponse(响应<名单,LT;相册和GT;>响应){
        ...
    }    @覆盖
    公共无效onFailure处(的Throwable t)的{
        //让下面的方法做重试的工作。
    }
});

有了这个,我必须要通过一个标准的回调 enqueueWithRetry 方法,它让我实现 onFailure处(尽管在previous方法我可以实现它太)

这就是我如何已经解决了这个问题。为更好的设计的任何建议将是AP preciated。

How can I add retry functionality to the requests sent by Retrofit 2 library. Something like:

service.listItems().enqueue(new Callback<List<Item>>() {
        @Override
        public void onResponse(Response<List<Item>> response) {
            ...
        }

        @Override
        public void onFailure(Throwable t) {
            ...
        }
    }).retryOnFailure(5 /* times */);

解决方案

I finally did something like this, for anyone interested:

1

First I made an abstract class CallbackWithRetry

public abstract class CallbackWithRetry<T> implements Callback<T> {

    private static final int TOTAL_RETRIES = 3;
    private static final String TAG = CallbackWithRetry.class.getSimpleName();
    private final Call<T> call;
    private int retryCount = 0;

    public CallbackWithRetry(Call<T> call) {
        this.call = call;
    }

    @Override
    public void onFailure(Throwable t) {
        Log.e(TAG, t.getLocalizedMessage());
        if (retryCount++ < TOTAL_RETRIES) {
            Log.v(TAG, "Retrying... (" + retryCount + " out of " + TOTAL_RETRIES + ")");
            retry();
        }
    }

    private void retry() {
        call.clone().enqueue(this);
    }
}

Using this class I can do something like this:

serviceCall.enqueue(new CallbackWithRetry<List<Album>>(serviceCall) {
    @Override
    public void onResponse(Response<List<Album>> response) {
        ...
    }
});


2

This is not completely satisfactory because I have to pass same serviceCall twice. This can confusing as one can think the second serviceCall (that goes into constructor of CallbackWithRetry) should or could be something different from first one (which we invoke enqueue method on it)

So I implemented a helper class CallUtils:

public class CallUtils {

    public static <T> void enqueueWithRetry(Call<T> call, final Callback<T> callback) {
        call.enqueue(new CallbackWithRetry<T>(call) {
            @Override
            public void onResponse(Response<T> response) {
                callback.onResponse(response);
            }

            @Override
            public void onFailure(Throwable t) {
                super.onFailure(t);
                callback.onFailure(t);
            }
        });
    }

}

And I can use it like this:

CallUtils.enqueueWithRetry(serviceCall, new Callback<List<Album>>() {
    @Override
    public void onResponse(Response<List<Album>> response) {
        ...
    }

    @Override
    public void onFailure(Throwable t) {
        // Let the underlying method do the job of retrying.
    }
});

With this I have to pass a standard Callback to enqueueWithRetry method and it makes me implement onFailure (Though in the previous method I can implement it too)

So this is how I've solved the issue. Any suggestion for a better design would be appreciated.

这篇关于使用重试2改造的要求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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