GSON & Realm String array

You might know about Realm, a fancy and practical storage option that one can use on Android. Realm is quite fast and it is really easy to work with but recently I had to parse some data from the webservice and I wanted to use GSON, the Android Json parser library. All works well if you do what it writes here but there is a problem on Realm when you want to store a list of Strings or Integers into your model. You just can’t!

The workaround/suggestion is to create a wrapper over String and use a list of that instead (which is not too nice/intuitive/etc.).

Given that, I had to created the following wrapper class:

/**
 * Created by catalin prata on 29/05/15.
 *
 * Wrapper over String to support setting a list of Strings in a RealmObject
 * To use it with GSON, please see RealmStringDeserializer
 *
 */
public class RealmString extends RealmObject {

    private String stringValue;

    public RealmString(){}

    public RealmString(String stringValue){
        this.stringValue =  stringValue;
    }


    public String getStringValue() {
        return stringValue;
    }

    public void setStringValue(String stringValue) {
        this.stringValue = stringValue;
    }

}

So we have our class using RealmList<RealmString> :

/**
 * Created by catalinprata on 29/05/15.
 */
public class MyCustomClass extends RealmObject {

    private RealmList<RealmString> strings;

    public RealmList<RealmString> getStrings() {
        return strings;
    }

    public void setStrings(RealmList<RealmString> strings) {
        this.strings = strings;
    }
}

 

Ok, nice, now I can set a List of RealmString objects to my entity that has a list of Strings.

Now we need to tell GSON that we have that crappy workaround so it can see it as a list of Strings, I’ve done that by doing a custom deserializer and implementing JsonDeserializer like this:

/**
 * Created by catalin prata on 29/05/15.
 * <p/>
 * Used to deserialize a list of realm string objects
 */
public class RealmStringDeserializer implements
        JsonDeserializer<RealmList<RealmString>> {

    @Override
    public RealmList<RealmString> deserialize(JsonElement json, Type typeOfT,
                                              JsonDeserializationContext context) throws JsonParseException {

        RealmList<RealmString> realmStrings = new RealmList<>();
        JsonArray stringList = json.getAsJsonArray();

        for (JsonElement stringElement : stringList) {
            realmStrings.add(new RealmString(stringElement.getAsString()));
        }

        return realmStrings;
    }
}

 

Ok, now we have the String wrapper and the GSON deserializer, the final thing would be to se the deserializer on the GsonBuilder before parsing the Json.

// the exclusion is for the Realm stackoverflow crash
GsonBuilder gsonBuilder = new GsonBuilder()
                .setExclusionStrategies(new ExclusionStrategy() {
                    @Override
                    public boolean shouldSkipField(FieldAttributes f) {
                        return f.getDeclaringClass().equals(RealmObject.class);
                    }

                    @Override
                    public boolean shouldSkipClass(Class<?> clazz) {
                        return false;
                    }
                });
// register the deserializer
gsonBuilder.registerTypeAdapter(new TypeToken<RealmList<RealmString>>() {
        }.getType(), new RealmStringDeserializer());

Gson gson = gsonBuilder.create();
// parse the Json
MyCustomClass myObject = gson.fromJson(reader, MyCustomClass.class);

And it should work just fine :P

 

 

 

 

 

Exit mobile version