Gson EnumTypeAdapter中的AssertionError在使用Proguard混淆时 [英] AssertionError in Gson EnumTypeAdapter when using Proguard Obfuscation

查看:338
本文介绍了Gson EnumTypeAdapter中的AssertionError在使用Proguard混淆时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目在序列化/反序列化过程中在 Gson 中实现了一个 TypeAdapter ,以保存对象的多态性状态。无论如何,该项目在开发测试期间工作正常,但是当它通过 proguard obfuscation 发布并测试时,它就会崩溃。

  03-21 10:06:53.632:E / AndroidRuntime(12441):致命异常:main 
03-21 10:06:53.632:E / AndroidRuntime(12441):java.lang。 AssertionError
03-21 10:06:53.632:E / AndroidRuntime(12441):at com.google.gson.internal.bind.TypeAdapters $ EnumTypeAdapter。< init>(SourceFile:724)
03 -21 10:06:53.632:E / AndroidRuntime(12441):在com.google.gson.internal.bind.TypeAdapters $ 26.create(SourceFile:753)
03-21 10:06:53.632:E / AndroidRuntime(12441):com.google.gson.Gson.getAdapter(SourceFile:353)
03-21 10:06:53.632:E / AndroidRuntime(12441):com.google.gson.internal.bind .ReflectiveTypeAdapterFactory $ 1.< init>(SourceFile:82)
03-21 10:06:53.632:E / AndroidRuntime(12441):com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(SourceFile: 81)
03-21 10 :06:53.632:E / AndroidRuntime(12441):在com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(SourceFile:118)
03-21 10:06:53.632:E / AndroidRuntime(12441) :at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(SourceFile:72)
03-21 10:06:53.632:E / AndroidRuntime(12441):com.google.gson.Gson.getAdapter (SourceFile:353)
03-21 10:06:53.632:E / AndroidRuntime(12441):at com.google.gson.Gson.toJson(SourceFile:578)
03-21 10:06 :53.632:E / AndroidRuntime(12441):在com.google.gson.Gson.toJsonTree(SourceFile:479)
03-21 10:06:53.632:E / AndroidRuntime(12441):com.google。 gson.Gson.toJsonTree(SourceFile:458)
03-21 10:06:53.632:E / AndroidRuntime(12441):com.google.gson.Gson $ 3.serialize(SourceFile:137)

我的Gson特定的proguard配置是:

  ## ---------------开始:Gson的proguard配置---------- 
#Gson使用泛型类型信息当使用字段时,存储在类文件中。 Proguard
#默认会删除这些信息,因此将其配置为保留所有信息。
-keepattributes签名

#使用GSON @Expose注释
-keepattributes *注释*

#Gson特定类
- 保持类sun.misc.Unsafe {*; }
#-keep class com.google.gson.stream。** {*; }

#将通过Gson序列化/反序列化的应用程序类
-keep class com.google.gson.examples.android.model。** {*; }

#这是我额外添加的,以排除gson混淆
-keep class com.google.gson。** {*; }

## --------------- End:Gson的proguard配置----------

我使用的 TypeAdapter 是:

  public final class GsonWorkshiftAdapter实现了JsonSerializer< IWorkshift>,JsonDeserializer< IWorkshift> {
private static final String CLASSNAME =CLASSNAME;
private static final String INSTANCE =INSTANCE;
$ b $ @Override
public JsonElement serialize(IWorkshift src,Type typeOfSrc,JsonSerializationContext context){
String className = src.getClass()。getCanonicalName();
JsonElement elem = context.serialize(src);

JsonObject retValue = new JsonObject();
retValue.addProperty(CLASSNAME,className);
retValue.add(INSTANCE,elem);

返回retValue;

$ b @Override
public IWorkshift deserialize(JsonElement json,Type typeOfT,JsonDeserializationContext context)throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
JsonPrimitive prim =(JsonPrimitive)jsonObject.get(CLASSNAME);
String className = prim.getAsString();

Class<?> klass = null;
try {klass = Class.forName(className); }
catch(ClassNotFoundException e){抛出新的JsonParseException(e.getMessage()); }

return context.deserialize(jsonObject.get(INSTANCE),klass);


$ / code $ / pre

我对这个错误进行了很多搜索, Gson,但找不到任何有用的答案。不过,我发现另一个问题类似的问题。



任何来自开发人员社区的帮助都不胜感激。

解决方案

看来我们必须要求保留枚举成员。
这对我有用:

  -keepclassmembers enum * {*;或者,如果你想更具体一些,可以购买








  -keepclassmembers enum com.your.package。** {*; } 


My project implements a TypeAdapter in Gson during serialization/deserialization for preserving object's polymorphism state. Anyhow, the project works fine during development tests, but when it is released with proguard obfuscation and tested, it just crashes.

03-21 10:06:53.632: E/AndroidRuntime(12441): FATAL EXCEPTION: main
03-21 10:06:53.632: E/AndroidRuntime(12441): java.lang.AssertionError
03-21 10:06:53.632: E/AndroidRuntime(12441):    at com.google.gson.internal.bind.TypeAdapters$EnumTypeAdapter.<init>(SourceFile:724)
03-21 10:06:53.632: E/AndroidRuntime(12441):    at com.google.gson.internal.bind.TypeAdapters$26.create(SourceFile:753)
03-21 10:06:53.632: E/AndroidRuntime(12441):    at com.google.gson.Gson.getAdapter(SourceFile:353)
03-21 10:06:53.632: E/AndroidRuntime(12441):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(SourceFile:82)
03-21 10:06:53.632: E/AndroidRuntime(12441):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(SourceFile:81)
03-21 10:06:53.632: E/AndroidRuntime(12441):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(SourceFile:118)
03-21 10:06:53.632: E/AndroidRuntime(12441):    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(SourceFile:72)
03-21 10:06:53.632: E/AndroidRuntime(12441):    at com.google.gson.Gson.getAdapter(SourceFile:353)
03-21 10:06:53.632: E/AndroidRuntime(12441):    at com.google.gson.Gson.toJson(SourceFile:578)
03-21 10:06:53.632: E/AndroidRuntime(12441):    at com.google.gson.Gson.toJsonTree(SourceFile:479)
03-21 10:06:53.632: E/AndroidRuntime(12441):    at com.google.gson.Gson.toJsonTree(SourceFile:458)
03-21 10:06:53.632: E/AndroidRuntime(12441):    at com.google.gson.Gson$3.serialize(SourceFile:137)

My Gson specific proguard configuration is:

##---------------Begin: proguard configuration for Gson  ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature

# For using GSON @Expose annotation
-keepattributes *Annotation*

# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }

#This is extra - added by me to exclude gson obfuscation
-keep class com.google.gson.** { *; }

##---------------End: proguard configuration for Gson  ----------

The TypeAdapter I'm using is:

public final class GsonWorkshiftAdapter implements JsonSerializer<IWorkshift>, JsonDeserializer<IWorkshift> {
    private static final String CLASSNAME = "CLASSNAME";
    private static final String INSTANCE  = "INSTANCE";

    @Override
    public JsonElement serialize(IWorkshift src, Type typeOfSrc, JsonSerializationContext context) {
        String className = src.getClass().getCanonicalName();
        JsonElement elem = context.serialize(src);

        JsonObject retValue = new JsonObject();
        retValue.addProperty(CLASSNAME, className);
        retValue.add(INSTANCE, elem);

        return retValue;
    }

    @Override
    public IWorkshift deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject jsonObject =  json.getAsJsonObject();
        JsonPrimitive prim = (JsonPrimitive) jsonObject.get(CLASSNAME);
        String className = prim.getAsString();

        Class<?> klass = null;
        try { klass = Class.forName(className); }
        catch (ClassNotFoundException e) { throw new JsonParseException(e.getMessage()); }

        return context.deserialize(jsonObject.get(INSTANCE), klass);
    }
}

I did a lot of search on this error specific to Gson, but couldn't find any helpful answer. However I found another question with the similar issue.

Any help from developer's community would be appreciated.

解决方案

It seems like we must request that enumerations' members are kept. This worked for me:

-keepclassmembers enum * { *; }

Or, if you want to be more specific,

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

这篇关于Gson EnumTypeAdapter中的AssertionError在使用Proguard混淆时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆