HttpLoggingInterceptor 干扰刷新令牌机制
HttpLoggingInterceptor interfering with with refresh token mechanism
我在我的 Android 应用中遇到了一个非常奇怪的问题 OkHttp3
Interceptor
我为不同的构建变体设置了不同的日志记录级别。
我在我的应用程序中设置了一个 OkHttp3
Interceptor
来拦截 API 请求,如果有任何 API returns 401
错误,拦截器从后端获取刷新的令牌并用新令牌更新原始请求的 header 并重复它。我们称之为 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中发生的事情:当请求returns 401时,进行了刷新调用,但没有任何反应然后。没有成功或失败的案例被调用(也许拦截器 Chain
中断但谁知道)。
这是我到目前为止尝试过的方法
- 完全删除 LoggingInterceptor -> 不起作用
- 将所有构建变体的日志记录级别设置为
Level.NONE
->
不工作
- 将所有构建变体的日志记录级别设置为
Level.BODY
-> 有效
像魔法一样
我今天也对此进行了很多搜索,但找不到任何 link 在日志记录级别之间搞乱其他拦截器。任何帮助将不胜感激,如果您需要更多代码,我可以 post 它。
问题是由 TokenRefreshInterceptor
中的 OkHttp3
Response
对象未关闭导致的内存泄漏引起的。我是在 Firebase Console
上知道这个泄漏的。使用后关闭此 Response
解决了问题。但是我仍然不确定为什么在启用正文级日志记录时它能正常工作。
我在我的 Android 应用中遇到了一个非常奇怪的问题 OkHttp3
Interceptor
我为不同的构建变体设置了不同的日志记录级别。
我在我的应用程序中设置了一个 OkHttp3
Interceptor
来拦截 API 请求,如果有任何 API returns 401
错误,拦截器从后端获取刷新的令牌并用新令牌更新原始请求的 header 并重复它。我们称之为 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中发生的事情:当请求returns 401时,进行了刷新调用,但没有任何反应然后。没有成功或失败的案例被调用(也许拦截器 Chain
中断但谁知道)。
这是我到目前为止尝试过的方法
- 完全删除 LoggingInterceptor -> 不起作用
- 将所有构建变体的日志记录级别设置为
Level.NONE
-> 不工作 - 将所有构建变体的日志记录级别设置为
Level.BODY
-> 有效 像魔法一样
我今天也对此进行了很多搜索,但找不到任何 link 在日志记录级别之间搞乱其他拦截器。任何帮助将不胜感激,如果您需要更多代码,我可以 post 它。
问题是由 TokenRefreshInterceptor
中的 OkHttp3
Response
对象未关闭导致的内存泄漏引起的。我是在 Firebase Console
上知道这个泄漏的。使用后关闭此 Response
解决了问题。但是我仍然不确定为什么在启用正文级日志记录时它能正常工作。