javaandroidenumsactiveandroid

ActiveAndroid TypeSerializer - list of enums


In my app I'm using ActiveAndoid.
In some models I have a column List<String> and in other List<MyEnum>.
I created a TypeSerializer for each type:

public class StringsListTypeSerializer extends TypeSerializer
{
    private static GsonBuilder sGsonBuilder;

    static{
        sGsonBuilder = new GsonBuilder();
    }

    @Override
    public Class<?> getDeserializedType() {
        return List.class;
    }

    @Override
    public Class<?> getSerializedType() {
        return String.class;
    }

    @Override
    public String serialize(Object data) {
        if(data == null){
            return null;
        }

        final Gson gson = sGsonBuilder.create();
        return gson.toJson(data);
    }

    @Override
    public List<String> deserialize(Object data) {
        if(data == null){
            return null;
        }

        final Gson gson = sGsonBuilder.create();
        List<String> strings = gson.fromJson(data.toString(), List.class);

        return strings;
    }
}

and for MyEnum (which is an enum type):

public class MyEnumListTypeSerializer extends TypeSerializer {

    private static GsonBuilder sGsonBuilder;

    static{
        sGsonBuilder = new GsonBuilder();
        sGsonBuilder.registerTypeAdapter(MyEnum.class, new MyEnumJsonDeserializer());
    }

    @Override
    public Class<?> getDeserializedType() {
        return new TypeToken<ArrayList<MyEnum>>(){}.getType().getClass();
    }

    @Override
    public Class<?> getSerializedType() {
        return String.class;
    }

    @Override
    public String serialize(Object data) {
        if(data == null){
            return null;
        }

        final Gson gson = sGsonBuilder.create();

        return gson.toJson(data);
    }

    @Override
    public ArrayList<MyEnum> deserialize(Object data) {
        if(data == null){
            return null;
        }

        final Gson gson = sGsonBuilder.create();
        Type listType = new TypeToken<ArrayList<MyEnum>>(){}.getType();
        ArrayList<MyEnum> myList = gson.fromJson(data.toString(), listType);

        return myList;
    }
}

My problem is that ActiveAndroid serialize the MyEnum list type as list of strings (with StringsListTypeSerializer) and on runtime when I use List<MyEnum> in for each loop I'm getting ClassCastException - can't cast String to Enum.
How to solve that problem?


Solution

  • The approach I have used to figure out different types

    public abstract class BaseGsonSerializer extends TypeSerializer {
    
        private Gson gson;
    
        public BaseGsonSerializer() {
            this.gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
        }
    
        @DebugLog
        @Override
        public Class<?> getSerializedType() {
            return String.class;
        }
    
        @Override
        @DebugLog
        public Class<?> getDeserializedType() {
            return TypeToken.get(getTypeDeserialize()).getRawType();
        }
    
        @Override
        public Object serialize(Object data) {
            if (data != null) {
                return gson.toJson(data);
            }
            return null;
        }
    
        @Override
        public Object deserialize(Object data) {
            if (data != null) {
                return gson.fromJson(data.toString(), getTypeDeserialize());
            }
            return null;
        }
    
        protected abstract Type getTypeDeserialize();
    
    }
    

    Following classes use BaseGsonSerializer

    public class PriceSerializer extends BaseGsonSerializer {
    
        protected Type getTypeDeserialize() {
            return new TypeToken<Price>() {
            }.getType();
        }
    }
    
    public class PriceListSerializer extends BaseGsonSerializer {
    
        protected Type getTypeDeserialize() {
            return new TypeToken<List<Price>>() {
            }.getType();
        }
    }
    

    This gives me exact what I want that is list of prices converted to json string and price object converted to json string

    Hope this could help you to fix your problem.