Android Retrofit如何为特定API单独设置超时 拦截器方案不生效
问题原因
你的自定义超时配置不生效核心是两个问题:
- OkHttp的
Interceptor.Chain是不可变对象,调用withConnectTimeout/withReadTimeout/withWriteTimeout方法不会修改当前chain实例,只会返回携带新超时配置的新chain对象。你的代码只是调用了方法生成新chain,但没有使用这个新chain执行请求,最终还是用原有默认配置的chain发起请求,超时规则自然不生效。 - 代码里请求头key存在拼写错误:
"Reuest_Id"少了字母q,和实际传的Request_Id不匹配的话,根本进不到超时配置的分支逻辑。
修复后的实现
修正后的拦截器代码如下:
class CustomTimeOutInterceptor(private val context: Context) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request() // 修正请求头拼写错误 val requestID = request.header("Request_Id") var currentChain = chain if (requestID?.equals(RequestID.USER_TYPE) == true) { // 把配置好新超时的chain赋值给变量,替换原有chain currentChain = currentChain .withConnectTimeout(10, TimeUnit.MILLISECONDS) .withWriteTimeout(10, TimeUnit.MILLISECONDS) .withReadTimeout(10, TimeUnit.MILLISECONDS) } // 用最终配置好的chain发起请求 return currentChain.proceed(request) } }
全局OkHttpClient的配置不需要额外调整,保持原有添加拦截器的写法即可:
final OkHttpClient okHttpClient = new OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .addInterceptor(new CustomTimeOutInterceptor(context)) .build();
补充说明
- 不需要移除全局默认超时配置,未匹配到规则的接口会自动沿用全局30秒的超时设置
- 10毫秒的超时阈值极短,正常网络请求甚至本地mock接口都很容易触发超时,测试时可以根据实际场景调整数值
- 如果你使用的是3.9.0之前的OkHttp版本,没有提供chain级别的withTimeout方法,需要单独构建一个配置对应超时的OkHttpClient实例,在拦截器内部用新client发起请求即可。
内容的提问来源于stack exchange,提问作者Android Killer
相关产品推荐
相关产品推荐

