【发布时间】:2020-06-30 19:52:22
【问题描述】:
我在使用 OkHttp3 Interceptor 的 Android 应用程序中遇到了一个非常奇怪的问题,我为不同的构建变体设置了不同的日志记录级别。
我在我的应用程序中设置了一个OkHttp3Interceptor 来拦截API 请求,如果任何API 返回401 错误,拦截器从后端获取刷新的令牌并使用新令牌更新原始请求的标头并重复它。我们称之为 RefreshTokenInterceptor。我在构建我的OKHttpClient 时添加了这个拦截器。除此之外,我还添加了一个 HttpLoggingInterceptor 来记录 API 请求和响应,或者在发布版本的情况下停止记录。我们称之为 LoggingInterceptor
这是我构建OkHttpClient 的代码。这段代码应该足够了,因为如果日志级别发生变化,刷新机制可以正常工作。
val loggingInterceptor = HttpLoggingInterceptor()
// changing level to Level.BODY in the below solves the issue,
// but I don't want to log the results
when {
BuildConfig.DEBUG -> loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
else -> loggingInterceptor.level = HttpLoggingInterceptor.Level.NONE
}
val httpClientBuilder = OkHttpClient.Builder()
.readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
.writeTimeout(WRITE_TIMEOUT, TimeUnit.MILLISECONDS)
.addInterceptor(ConnectivityInterceptor())
.addInterceptor(TokenRefreshInterceptor())
.addInterceptor(loggingInterceptor)
.connectTimeout(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)
当我在两种情况下都将 LoggingInterceptor 的日志记录级别设置为 Level.BODY 时,一切正常。但是如果日志级别设置为Level.NONE,令牌刷新机制就会停止工作。
更具体地说,在这种情况下,这就是 RefreshTokenInterceptor 中发生的情况:当请求返回 401 时,会进行刷新调用,但之后没有任何反应。没有成功或失败案例被调用(也许拦截器 Chain 中断但谁知道)。
这是我目前尝试过的
- 完全删除 LoggingInterceptor -> 不起作用
- 将所有构建变体的日志级别设置为
Level.NONE-> 确实 不工作 - 将所有构建变体的日志记录级别设置为
Level.BODY-> 有效 像魔术一样
我今天也对此进行了很多搜索,但找不到日志级别之间的任何链接,从而弄乱了其他拦截器。任何帮助将不胜感激,如果您需要更多代码,我可以发布它。
【问题讨论】:
-
您可以尝试在 TokenRefreshInterceptor 之前先添加 loggingInterceptor 吗?不确定,但它可能与请求/响应链接有关。另外,您可以发布您的 TokenRefreshInterceptor 代码吗?
-
实际上问题是由未关闭的 OkHttp3 Response 对象创建的 RefreshTokenInterceptor 中的内存泄漏引起的。当我关闭它时,问题就解决了。
标签: android okhttp interceptor