ProtocolException:太多后续请求:Android 中使用 Proguard 和 OkHttp 3.0 的 21 个
Posted
技术标签:
【中文标题】ProtocolException:太多后续请求:Android 中使用 Proguard 和 OkHttp 3.0 的 21 个【英文标题】:ProtocolException: Too many follow-up requests: 21 with Proguard and OkHttp 3.0 in Android 【发布时间】:2017-03-29 01:22:20 【问题描述】:我正在使用 Retrofit 2.1.0 和 OkHttp 3.4.2 创建一个应用程序。
在调试模式下,将 minifyEnabled 设置为 false,一切正常,但是一旦我将 minifyEnabled 更改为 true,我就会得到以下异常:
HTTP FAILED: java.net.ProtocolException: Too many follow-up requests: 21
我的 OkHttp 的 Proguard 规则如下:
-keep class com.squareup.okhttp3.**
*;
-dontwarn okhttp3.**
-dontwarn okio.**
我不明白为什么会抛出这个异常,也不明白为什么应用程序似乎发出了 21 个跟进请求。谁能帮帮我?
【问题讨论】:
【参考方案1】:我刚刚遇到了同样的错误:java.net.ProtocolException: Too many follow-up requests: 21
。为了您的兴趣,我使用的是 Retrofit 2.5.0 和 OkHttp 3.14.1,尽管版本并不重要。
我也只有在启用 Proguard 时才会出现此错误(实际上我使用的是 R8,但结果是一样的)。这很重要,并暗示了根本原因。
有什么问题?我使用 OAuth 进行身份验证,像往常一样添加“授权”标头。当令牌过期时,服务器会发送 401 Unauthorized。由于我使用 OkHttp Authenticator
来刷新令牌,所以当收到 401 时会调用 authenticate
方法。
问题是我使用 Gson 解析这个 401 Unauthorized 请求的响应,像这样:
override fun authenticate(route: Route?, response: Response): Request?
val responseError: ResponseError? = response.body()?.let
Gson().fromJson(it.string(), ResponseError::class.java) // <- Fails!
// Check server response and decide if should refresh token...
但是由于 ResponseError
类被 proguard 混淆了,它的字段与服务器发送的 JSON 的名称不匹配,这使得 Gson().fromJson
失败,因此令牌不是神清气爽。结果是重复执行网络调用,直到抛出异常。
修复很简单。只需将@Keep
添加到ResponseError
:
import androidx.annotation.Keep
@Keep
data class ResponseError(
val error: String? = null,
val error_description: String? = null
)
由于您的问题仅发生在启用 proguard 的情况下,因此请求或响应类可能被混淆,从而导致 JSON 解析失败。或者,您可能正在使用带有混淆类的 Gson.fromJson
和 Gson.fromJson
将一些 JSON 保存到共享首选项。
要解决此问题,请将@SerializedName
和/或@Keep
添加到您的所有请求和响应中(特别是枚举,这会带来更多麻烦)。或者,您可以简单地将所有请求和响应放入一个包和exclude it。除了请求和响应之外,还要特别注意任何Gson.fromJson
和Gson.fromJson
呼叫。
为了帮助诊断问题,您可以通过检查在app/build/outputs/mapping/release/mapping.txt
中找到的映射文件(对于发布版本)来检查 proguard/R8 的功能。它包含 proguard/R8 对您的代码所做的所有转换。
您还可以通过 Build -> Analyze APK... 分析 APK... 您会以非常简单的方式查看哪些类被混淆了。您可以同时分析 2 个 APK(一个已缩小,一个未缩小)并进行比较。
【讨论】:
以上是关于ProtocolException:太多后续请求:Android 中使用 Proguard 和 OkHttp 3.0 的 21 个的主要内容,如果未能解决你的问题,请参考以下文章
java.net.ProtocolException:方法不支持请求正文:GET
WCF ProtocolException:错误请求 400(与 http 消息大小有关)