Android 的 ProGuard 和 Retrofit2 转换器 Gson?
ProGuard for Android and Retrofit2 Converter Gson?
我在我的项目中使用 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 配置?
你要么想保留你在 gson 中使用的 class,要么使用 @SerializedName
注释。
选项 1(保留 class)
// all classes in a package
-keep class com.example.app.json.** { *; }
// or a specific class
-keep class com.example.app.json.SpecificClass { *; }
选项 2(使用 @SerializedName
):
public class YourJsonClass{
@SerializedName("name") String username;
public MyClass(String username) {
this.username = username;
}
}
使用第二个选项 proguard 仍然会混淆 class 和字段名称,但 gosn 可以使用注释为每个字段获取正确的名称
用 @Keep
注释您的 JSON 模型 类。
在我的例子中,我使用 Moshi for JSON 和 Retrofit,但问题是一样的。它在调试中工作,但在使用 ProGuard 构建之后,使用模型的 RecyclerView 崩溃并出现 NullPointerException,因为列表中充满了空模型对象,因为 Moshi 无法识别任何字段。我认为 Gson 也会发生同样的事情。
一种解决方案是用相应的序列化名称注释每个字段:
@Json(name="username") String username;
这样 ProGuard 就可以在不破坏转换的情况下混淆变量名。
另一个解决方案是在 proguard-rules.pro
文件中添加一个 "keep" 选项,就像 Dodge 建议的那样
-keep public class com.example.model.User
像 authToken
一样,在你想要的 class 上使用 android @Keep 注释
@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 *
如果您使用 jsonschema2pojo,每个字段都带有
注释
@SerializedName(field)
只需将此添加到您的 proguard-rules.pro 中,即可将每个字段名保留为 @SerializedName。
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}
我在我的项目中使用 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 配置?
你要么想保留你在 gson 中使用的 class,要么使用 @SerializedName
注释。
选项 1(保留 class)
// all classes in a package -keep class com.example.app.json.** { *; } // or a specific class -keep class com.example.app.json.SpecificClass { *; }
选项 2(使用 @SerializedName
):
public class YourJsonClass{ @SerializedName("name") String username; public MyClass(String username) { this.username = username; } }
使用第二个选项 proguard 仍然会混淆 class 和字段名称,但 gosn 可以使用注释为每个字段获取正确的名称
用 @Keep
注释您的 JSON 模型 类。
在我的例子中,我使用 Moshi for JSON 和 Retrofit,但问题是一样的。它在调试中工作,但在使用 ProGuard 构建之后,使用模型的 RecyclerView 崩溃并出现 NullPointerException,因为列表中充满了空模型对象,因为 Moshi 无法识别任何字段。我认为 Gson 也会发生同样的事情。
一种解决方案是用相应的序列化名称注释每个字段:
@Json(name="username") String username;
这样 ProGuard 就可以在不破坏转换的情况下混淆变量名。
另一个解决方案是在 proguard-rules.pro
文件中添加一个 "keep" 选项,就像 Dodge 建议的那样
-keep public class com.example.model.User
像 authToken
一样,在你想要的 class 上使用 android @Keep 注释@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 *
如果您使用 jsonschema2pojo,每个字段都带有
注释@SerializedName(field)
只需将此添加到您的 proguard-rules.pro 中,即可将每个字段名保留为 @SerializedName。
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}