Gson抽象类(de)序列化

时间:2015-01-02 03:41:18

标签: java android gson

我有一个抽象类:

public abstract class Measurement {

    String Name;
    String Value;

    abstract void setName(String name);
    abstract Object getName();
    abstract void setValue(String value);
    abstract Object getValue();

    @Override
    abstract public String toString();
}

以及其中几个具体版本:

public class BasicMeasurement extends Measurement {
       //removed for brevity's sake
}

最后,一个用于序列化到磁盘存储的Utility类

public class Config {
        public List<Measurement> Measurements;
        public HashMap<String,String> Items;

        public Config(){
            Measurements = new ArrayList<Measurement>();
            Items = new HashMap<>();
        }


    }

我正在使用Gson(de)将此Config类序列化为磁盘并返回。 序列化到磁盘工作正常,但是,由于抽象类而反序列化爆炸。

所以我开始遵循指示here,当我意识到需要进行一些重大修改才能在我的用例中使用。

问:最好(de)序列化我的配置类的方法是什么(1)不会爆炸2.反序列化时不会导致信息丢失(即使它没有爆炸,反序列化类型测量会导致特定具体值的丢失)

当前保存方法

public boolean SaveSettings() {
        try {
            FileOutputStream fileOutputStream = mActivity.openFileOutput(SETTINGS_FILE_NAME, Context.MODE_PRIVATE);
            this.json = gson.toJson(this.Config);
            fileOutputStream.write(this.json.getBytes());
            fileOutputStream.close();
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

当前加载方法

public static MeasureSettings LoadSettings(Activity activity) throws Exception {
       MeasureSettings measureSettings = new MeasureSettings(activity);
       measureSettings.json = measureSettings.getStringFromFile(SETTINGS_FILE_NAME);
       if(measureSettings.json.length() != 0) {
           measureSettings.Config = gson.fromJson(measureSettings.json, Config.class);
       }
       measureSettings.SaveSettings();
       return measureSettings;
   }

1 个答案:

答案 0 :(得分:1)

所以我的假设是正确的,我在Config类中添加的层次结构确实是bjork自定义序列化器/反序列化器。

然而,我能解决问题,仍然使用自定义反序列化器。

DeSerializer - 这仅用于我的ArrayList

中的项目
@Override
        public A deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
                throws JsonParseException {
            JsonObject jsonObject = json.getAsJsonObject();
            String type = jsonObject.get("MyType").getAsString();
            try {
                // String thePackage = "com.onetwentyonegwatt.MeasurementLib";
                return context.deserialize(json, Class.forName(type));
            } catch (ClassNotFoundException e) {
                throw new JsonParseException("Unknown element type: " + type, e);
            }
        }

在此使用:

public static MeasureSettings LoadSettings(Activity activity) throws Exception {
       MeasureSettings measureSettings = new MeasureSettings(activity);
       measureSettings.json = measureSettings.getStringFromFile(SETTINGS_FILE_NAME);
       if(measureSettings.json.length() != 0) {
          JsonParser jsonParser = new JsonParser();
          JsonObject o = (JsonObject)jsonParser.parse(measureSettings.json);
          JsonElement items = o.get("Items");
          measureSettings.Config.Items = gson.fromJson(items,measureSettings.Config.Items.getClass());
          JsonElement measurements = o.get("Measurements");
          for(JsonElement item : measurements.getAsJsonArray()) //Iterating the ArrayList values(As json array) here and then deserializing one by one.
           {
               // deserialize(item,Class.forName(item.getAsJsonObject().get("MyType").getAsString()),context);
               String className = item.getAsJsonObject().get("MyType").getAsString();
               Class<?> type = Class.forName(className);
               Measurement l = (Measurement)measureSettings.gsonBuilder.create().fromJson(item,Class.forName(className));
               measureSettings.Config.Measurements.add(l);
           }
           //measureSettings.Config = measureSettings.gsonBuilder.create().fromJson(measureSettings.json,Config.class);
       }
       measureSettings.SaveSettings();
       return measureSettings;
   }