如何在okhttp中更改请求的超时

问题描述 投票:4回答:3

通常我们为okHttp客户端设置超时,我们使用该客户端的单个实例。因此,一旦生成,我们就无法更改该客户端的超时。

如何更改特定请求的超时?反正有没有创建新客户端?

一些呼叫需要花费更多时间至少每个应用程序1/2,这需要比其他呼叫更多的超时。如果请求可以覆盖默认超时,那将是很好的。

okhttp okhttp3 okhttpclient
3个回答
4
投票

在3.9中,可以在拦截器中为每个请求设置此值

https://github.com/square/okhttp/blob/36bd68aa3e93affb12504cd40454e64c6812019c/okhttp-tests/src/test/java/okhttp3/InterceptorTest.java#L747-L757

  @Test public void chainWithReadTimeout() throws Exception {
    Interceptor interceptor1 = new Interceptor() {
      @Override public Response intercept(Chain chainA) throws IOException {
        assertEquals(5000, chainA.readTimeoutMillis());

        Chain chainB = chainA.withReadTimeout(100, TimeUnit.MILLISECONDS);
        assertEquals(100, chainB.readTimeoutMillis());

        return chainB.proceed(chainA.request());
      }
    };
  }

5
投票

请参阅https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/PerCallSettings.java,它创建只修改某些设置的浅克隆。

// Copy to customize OkHttp for this request.
OkHttpClient client2 = client.newBuilder()
    .readTimeout(3000, TimeUnit.MILLISECONDS)
    .build();

4
投票

更新到Retrofit 2.5.0你可以使用Invocation

新增内容:Invocation类提供对调用的方法和参数列表的引用,作为底层OkHttp调用的标记。这可以从OkHttp拦截器访问,用于记录,分析或度量聚合等事情。

这样,您可以创建一个SpecificTimeout注释,仅用于设置不同超时持续时间所需的请求,并在OkHttp Interceptor上读取其值以更改该点的超时。

自定义注释

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SpecificTimeout {
    int duration();
    TimeUnit unit();
}

服务接口

public interface GitHubService {
    @GET("/users")
    @SpecificTimeout(duration = 5000, unit = TimeUnit.MILLISECONDS)
    Call<List<User>> listUsers();

    @GET("/repos")
    @SpecificTimeout(duration = 15000, unit = TimeUnit.MILLISECONDS)
    Call<List<Repo>> listRepos();
}

拦截器

class TimeoutInterceptor implements Interceptor {

    @NonNull
    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {
        Request request = chain.request();

        final Invocation tag = request.tag(Invocation.class);
        final Method method = tag != null ? tag.method() : null;
        final SpecificTimeout timeout = method != null ? method.getAnnotation(SpecificTimeout.class) : null;

        if (timeout != null) {
           return chain.withReadTimeout(timeout.value(), timeout.unit())
                       .withConnectTimeout(timeout.value(), timeout.unit())
                       .withWriteTimeout(timeout.value(), timeout.unit())
                       .proceed(request);
        }

        return chain.proceed(request);
    }
}

OkHttp Builder

OkHttpClient okHttpClient = new OkHttpClient.Builder()
                //default timeout for not annotated requests
                .readTimeout(10000, TimeUnit.MILLISECONDS)
                .connectTimeout(10000, TimeUnit.MILLISECONDS)
                .writeTimeout(10000, TimeUnit.MILLISECONDS)
                .addInterceptor(new TimeoutInterceptor())
                .build();
© www.soinside.com 2019 - 2024. All rights reserved.