Retrofit 2单API重复请求问题求助:单次调用触发三次请求
首先,咱们先梳理下你遇到的核心问题:调用一次API却触发三次请求,间隔极短,这大概率是自动重试、重定向或者代码逻辑重复调用导致的,咱们逐个排查:
1. 禁用OkHttpClient的自动重试机制
OkHttpClient默认会在连接失败、IO异常或者某些服务器错误(5xx)时自动重试请求,这很可能是你看到三次请求的原因。你可以在构建OkHttpClient时明确禁用重试:
修改你的retrofit()方法中OkHttpClient.Builder的配置,添加retryOnConnectionFailure(false):
builder.addInterceptor(new Interceptor() { // 你的拦截器逻辑... }) .connectTimeout(60, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS) .writeTimeout(60, TimeUnit.SECONDS) .retryOnConnectionFailure(false); // 添加这一行禁用自动重试
2. 检查AddToEnqueue方法是否重复调用了enqueue
你的Activity代码中调用了RetroConnect.getInstance().AddToEnqueue(...),需要确认这个方法内部是否只调用了一次call.enqueue()。如果这个方法里不小心多次执行了enqueue,就会导致多次请求。
比如检查AddToEnqueue的实现:
public void AddToEnqueue(Call call, RetroResponseListener listener, RequestType requestType) { // 确保这里只调用一次call.enqueue() call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { // 处理响应 } @Override public void onFailure(Call call, Throwable t) { // 处理失败 } }); }
如果这个方法被多次调用,或者内部有循环、重复逻辑,都会触发多次请求。
3. 排查服务器重定向问题
如果服务器返回了3xx的重定向状态码(比如301、302),OkHttpClient默认会自动跟随重定向,这也会产生多次请求。你可以通过日志拦截器查看响应的状态码:
在debug模式下,日志拦截器会打印响应的状态码,如果看到多个3xx的响应,说明是重定向导致的。如果不需要跟随重定向,可以添加:
builder.followRedirects(false); // 禁用自动重定向
不过一般不建议禁用,最好和后端确认是否存在不必要的重定向。
4. 确保Retrofit和OkHttpClient的单例正确性
检查你的RetroConnect类是否是正确的单例模式,避免每次调用getInstance()都创建新的实例,导致重复构建Retrofit和拦截器。比如:
public class RetroConnect { private static RetroConnect sInstance; private Retrofit mRetrofit; private OkHttpClient.Builder mBuilder; // 私有构造函数,防止外部实例化 private RetroConnect() {} // 线程安全的单例获取方法 public static synchronized RetroConnect getInstance() { if (sInstance == null) { sInstance = new RetroConnect(); } return sInstance; } // 你的retrofit()方法... }
如果单例实现有问题,可能导致多次创建Retrofit实例,但这一般不会直接导致三次请求,但也是潜在的隐患。
5. 检查拦截器是否存在重复执行逻辑
你的自定义拦截器中,有没有可能触发了多次请求?比如不小心调用了多次chain.proceed(request)?看你的代码,拦截器最后只返回了一次chain.proceed(request),所以这个应该没问题,但可以再确认下拦截器的逻辑是否正确。
按照上面的步骤排查,应该能找到重复请求的原因。先从禁用自动重试开始试,这是最常见的原因。
内容的提问来源于stack exchange,提问作者sree

