In general we set timeout for the okHttp client and we use single instance of that client. So, we can't change the timeout for that client once it's generated.
How to change the timeout for a particular request ?? Is there anyway to do it without creating new client??
It's very common that some calls take more time atleast 1/2 per app, which needs more timeout than others. it would be great if request can override the default timeout.
Updating to Retrofit 2.5.0 you can use Invocation
class
New: Invocation class provides a reference to the invoked method and argument list as a tag on the underlying OkHttp Call. This can be accessed from an OkHttp interceptor for things like logging, analytics, or metrics aggregation.
In that way, you can create a SpecificTimeout
annotation to be used only on the requests you need to set a different timeout duration and read its values on an OkHttp Interceptor
to change the timeout at that point.
Custom Annotation
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SpecificTimeout {
int duration();
TimeUnit unit();
}
Service Interface
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();
}
Interceptor
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.duration(), timeout.unit())
.withConnectTimeout(timeout.duration(), timeout.unit())
.withWriteTimeout(timeout.duration(), 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();
See https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/PerCallSettings.java which creates shallow clones that only modify some settings.
// Copy to customize OkHttp for this request.
OkHttpClient client2 = client.newBuilder()
.readTimeout(3000, TimeUnit.MILLISECONDS)
.build();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With