适用于 Android 的 ProGuard 和 Retrofit2 转换器 Gson?

问题描述 投票:0回答:6

我在我的项目中使用 ProGuard,但它在 new Gson().toJson(Request); 中给出了错误的数据

我要出去了

{"a":"manage","b":"689184d4418b6d975d9a8e53105d3382","c":"10","d":"76"}

而不是

{"username":"manage","password":"689184d4418b6d975d9a8e53105d3382","value":"10","store":"76"}

我的 ProGuard 规则

-dontwarn okio.**
-dontwarn retrofit2.Platform$Java8
-dontwarn sun.misc.Unsafe
-dontwarn org.w3c.dom.bootstrap.DOMImplementationRegistry
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-keepclassmembers class rx.internal.util.unsafe.** {
    long producerIndex;
    long consumerIndex;
}

-keepclasseswithmembers class * {
    @retrofit2.http.* <methods>;
}
-keep class com.google.gson.** { *; }
-keep class com.google.inject.** { *; }

我正在使用

 compile 'com.squareup.retrofit2:converter-gson:2.0.0'

Android 中的 Retrofit2:converter-gson 有新的推荐 ProGuard 配置吗?

android gson proguard retrofit2 android-proguard
6个回答
22
投票

您要么想保留正在使用 gson 的类,要么使用

@SerializedName
注释。

选项 1(继续上课)

// 包中的所有类
-保留类 com.example.app.json.** { *; }
// 或特定类
-保留类 com.example.app.json.SpecificClass { *; }

选项 2(使用

@SerializedName
):

公共类YourJsonClass{
   @SerializedName("name") 字符串用户名;

   公共MyClass(字符串用户名){
     this.用户名 = 用户名;
   }
 }

使用第二个选项 proguard 仍然会混淆类和字段名称,但 gosn 可以使用注释来获取每个字段的正确名称


8
投票

使用

@Keep
注释您的 JSON 模型类。


5
投票

在您想要的类上使用 android @Keep 注释,例如 authToken

@Keep
data class AuthToken(
    var access_token: String,
    var token_type: String,
    var expires_in: String,
    var userName: String,
    var issued: String,
    var expires: String) {}

然后在 ProGuard 中添加以下行:
如果使用 androidx

-keep @androidx.annotation.Keep public class *

否则

 -keep @android.support.annotation.Keep public class *

0
投票

就我而言,我使用 Moshi for JSON with Retrofit,但问题是一样的。它在调试中工作,但在使用 ProGuard 构建后,使用该模型的 RecyclerView 因 NullPointerException 崩溃,因为列表充满了空模型对象,因为 Moshi 无法识别任何字段。我认为 Gson 也会发生同样的事情。

一种解决方案是用相应的序列化名称注释每个字段:

@Json(name="username") String username;

这样 ProGuard 可以混淆变量名称而不破坏转换。

另一个解决方案是在

proguard-rules.pro
文件中添加一个“保留”选项,就像Dodge建议的那样

-keep public class com.example.model.User

0
投票

如果您使用 jsonschema2pojo 每个字段都带有注释

@SerializedName(字段)

只需将其添加到您的 proguard-rules.pro 即可将每个字段名称保留为 @SerializedName。

-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
}

0
投票

我也遇到了同样的问题,但这个解决方案对我有用 https://stackoverflow.com/revisions/76073318/4

© www.soinside.com 2019 - 2024. All rights reserved.