【问题标题】:ProGuard for Android and Retrofit2 Converter Gson?ProGuard for Android 和 Retrofit2 Converter Gson?
【发布时间】:2016-12-02 13:45:53
【问题描述】:

我在我的项目中使用 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 中是否有新的推荐 ProGuard 配置用于 retrofit2:converter-gson?

【问题讨论】:

  • 最简单的方法是保留您想要与 gson 一起使用的类。否则你可能想看看gson是否有一个注释来给一个字段一个名字——这就是我在我的应用程序中使用jackson的方式。
  • 如何保留课程..任何规则

标签: android gson proguard retrofit2 android-proguard


【解决方案1】:

您要么想通过 gson 保留正在使用的类,要么使用 @SerializedName 注释。

选项 1(继续上课)

// 一个包中的所有类 -keep class com.example.app.json.** { *; } // 或特定的类 -keep class com.example.app.json.SpecificClass { *; }

选项 2(使用 @SerializedName):

公共类 YourJsonClass{ @SerializedName("name") 字符串用户名; 公共MyClass(字符串用户名){ this.username = 用户名; } }

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

【讨论】:

  • 我们还需要{ *; } 在“-keep class com.example.app.json.SpecificClass”之后?
【解决方案2】:

使用 @Keep 注释您的 JSON 模型类。

【讨论】:

  • @ralphgabb 通常你会提供两个带有规则的文件来保护。一个来自 sdk,一个来自 yoir 项目。来自 sdk 的那个包含除其他外,使用 Keep 注释类的规则。确保你有那个。
【解决方案3】:

在你想要的类上使用 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 *

【讨论】:

    【解决方案4】:

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

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

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

    这样 ProGuard 可以在不破坏转换的情况下混淆变量名。

    另一种解决方案是在 proguard-rules.pro 文件中添加像 Dodge 建议的“保留”选项

    -keep public class com.example.model.User
    

    【讨论】:

      【解决方案5】:

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

      @SerializedName(字段)

      只需将其添加到您的 proguard-rules.pro 中,以通过 @SerializedName 保留每个字段名。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-25
        • 2014-07-12
        • 1970-01-01
        • 2015-03-31
        • 2016-12-20
        • 1970-01-01
        • 1970-01-01
        • 2016-02-11
        相关资源
        最近更新 更多