当我在 GSON(使用枚举)上运行 Proguard 时应用程序崩溃

Posted

技术标签:

【中文标题】当我在 GSON(使用枚举)上运行 Proguard 时应用程序崩溃【英文标题】:App crashing when I run Proguard on GSON (which using enum) 【发布时间】:2014-06-03 01:29:17 【问题描述】:

我在我的 android 应用中使用 GSON 来解析数据。我在我的模型对象中添加了一个枚举。添加枚举后,我的应用程序开始崩溃。当我将 runProguard 设为 false 时,一切正常。当程序为真时,我尽我所能在互联网上找到解决问题的方法。但仍然没有运气。

我已经在 proguard-rule 文件中做了以下事情

-keep class com.google.**  *; 

-keepattributes *Annotation*
-keepattributes Signature

-keepclassmembers enum *  public static **[] values(); public static ** valueOf(java.lang.String); 

枚举材料示例:

public enum TypeX 
@SerializedName("live")
LIVE,

@SerializedName("upcoming")
UPCOMING,

@SerializedName("replay")
REPLAY; 

我的堆栈跟踪

java.lang.AssertionError
        at com.google.gson.internal.bind.TypeAdapters$EnumTypeAdapter.<init>(Unknown Source)
        at com.google.gson.internal.bind.TypeAdapters$26.create(Unknown Source)
        at com.google.gson.Gson.getAdapter(Unknown Source)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(Unknown Source)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(Unknown Source)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(Unknown Source)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(Unknown Source)
        at com.google.gson.Gson.getAdapter(Unknown Source)
        at com.google.gson.internal.bind.CollectionTypeAdapterFactory.create(Unknown Source)
        at com.google.gson.Gson.getAdapter(Unknown Source)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(Unknown Source)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(Unknown Source)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(Unknown Source)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(Unknown Source)
        at com.google.gson.Gson.getAdapter(Unknown Source)
        at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(Unknown Source)
        at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(Unknown Source)
        at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(Unknown Source)
        at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(Unknown Source)
        at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(Unknown Source)
        at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(Unknown Source)
        at com.google.gson.Gson.toJson(Unknown Source)
        at com.google.gson.Gson.toJson(Unknown Source)
        at com.google.gson.Gson.toJson(Unknown Source)
        at com.google.gson.Gson.toJson(Unknown Source)
        at com.theice.gsonapp.app.MainActivity.a(Unknown Source)
        at com.theice.gsonapp.app.MainActivity.onCreate(Unknown Source)
        at android.app.Activity.performCreate(Activity.java:5231)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
        at android.app.ActivityThread.access$800(ActivityThread.java:135)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5017)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
        at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

【参考方案1】:

这应该通过使用以下规则来解决:

-keepclassmembers enum *  *; 

或使用以下内容:

-keepclassmembers enum com.your.package.**  *; 

相关回答:https://***.com/a/30167048/4758255

【讨论】:

这对我来说是正确的答案。在 proguard 中添加以下行解决了我的问题: -keepclassmembers enum * *; 【参考方案2】:

我通过在我的 proguard-rule 文件中添加这些规则解决了这个问题:

    # GSON.
-keepnames class com.google.gson.** *;
-keepnames enum com.google.gson.** *;
-keepnames interface com.google.gson.** *;
-keep class com.google.gson.**  *; 
-keepnames class org.** *;
-keepnames enum org.** *;
-keepnames interface org.** *;
-keep class org.**  *; 

-keepnames class com.yourpackagename.net.** *;
-keepnames enum com.yourpackagename.net.** *;
-keepnames interface com.yourpackagename.net.** *;
-keep class com.yourpackagename.net.**  *; 

-keepattributes Signature
-keepattributes *Annotation*
-keep class sun.misc.Unsafe  *; 
-keep class com.google.gson.stream.**  *; 

-keepclassmembers enum * 
    public static **[] values();
    public static ** valueOf(java.lang.String);

【讨论】:

【参考方案3】:

请确认以下事项-

    在app目录下添加proguard-rules.pro文件。

    在 build.gradle(module:app) 文件中定义的路径是正确的,如下所示 -

proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

    如果以上两个步骤都可以,请在 progaurd 文件中添加以下行(规则)-

    -keepclassmembers 枚举 * *;

    清理,构建项目并再次运行。

【讨论】:

以上是关于当我在 GSON(使用枚举)上运行 Proguard 时应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

在使用 GSON 解析 JSON 时使用枚举

在使用 GSON 解析 JSON 时使用枚举

获取java.lang.NoClassDefFoundError:com / google / gson / gson

PHP API 不能与改造/gson 结合使用

iPhone 和 iPad 之间的不同行为与资产库

谷歌 gson 在安卓上运行吗?