Chr*_*sen 9 android proguard android-proguard retrofit2 okhttp3
我正在使用Retrofit 2.1.0和OkHttp 3.4.2创建一个应用程序.
在minifyEnabled设置为false的调试模式下,一切都运行良好但只要我将minifyEnabled更改为true,我就会得到以下异常:
HTTP FAILED: java.net.ProtocolException: Too many follow-up requests: 21
Run Code Online (Sandbox Code Playgroud)
我的Proguard OkHttp规则如下:
-keep class com.squareup.okhttp3.** {
*;
}
-dontwarn okhttp3.**
-dontwarn okio.**
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么抛出此异常,我不明白为什么该应用程序似乎正在提出21个跟进请求.谁能帮我?
我刚刚遇到了完全相同的错误:java.net.ProtocolException: Too many follow-up requests: 21。为了您的兴趣,我使用的是 Retrofit 2.5.0 和 OkHttp 3.14.1,尽管版本并不重要。
我也只有在启用 Proguard 时才会出现此错误(实际上我使用的是 R8,但结果是相同的)。这很重要,并暗示了根本原因。
有什么问题?我使用 OAuth 进行身份验证,像往常一样添加“授权”标头。当令牌过期时,服务器会发送 401 Unauthorized。由于我使用 OkHttpAuthenticator刷新令牌,因此当收到 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...
}
Run Code Online (Sandbox Code Playgroud)
但由于该类ResponseError被混淆器混淆,它的字段与服务器发送的 JSON 名称不匹配,这会导致Gson().fromJson失败,因此令牌不会刷新。结果是重复执行网络调用,直到抛出异常。
修复是微不足道的。只需添加@Keep到ResponseError:
import androidx.annotation.Keep
@Keep
data class ResponseError(
val error: String? = null,
val error_description: String? = null
)
Run Code Online (Sandbox Code Playgroud)
由于您的问题仅在启用混淆器时发生,因此很可能请求或响应类被混淆,这使得 JSON 解析失败。或者,您可能会使用混淆的类将一些 JSON 保存到共享首Gson.fromJson选项Gson.fromJson。
要解决问题,请在所有请求和响应中添加@SerializedName和/或(特别是枚举,这会带来更多麻烦)。@Keep或者,您可以简单地将所有请求和响应放入一个包中并将其排除。除了请求和响应之外,还要特别注意任何Gson.fromJson和Gson.fromJson调用。
为了帮助诊断问题,您可以通过检查您将在其中找到的映射文件app/build/outputs/mapping/release/mapping.txt(对于发布版本)来检查 proguard/R8 的功能。它包含 proguard/R8 对您的代码所做的所有转换。
您还可以通过执行“构建”->“分析 APK”来分析 APK...您将看到哪些类正在以非常简单的方式被混淆。您可以同时分析 2 个 APK(一个已缩小,一个未缩小)并进行比较。
| 归档时间: |
|
| 查看次数: |
2433 次 |
| 最近记录: |