Search code examples
androidgsonrealmretrofit

Android Retrofit + Realm + Gson: Serializer not called


I'm having a bit of an issue with my custom serializers working with Retrofit, Realm and Gson. Here I am registering type adapters for my three classes:

GsonBuilder builder = new GsonBuilder();
        // Register type adapters to modify outgoing json according to server requirements.
        try {
            builder
                    .registerTypeAdapter(Class.forName("io.realm.UserProxy"), new UserSerializer())
                    .registerTypeAdapter(Class.forName("io.realm.FavoriteSongProxy"), new FavoriteSongSerializer())
                    .registerTypeAdapter(Class.forName("io.realm.ArtistProxy"), new ArtistSerializer())
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }

        Gson gson = builder.create();

        return new Retrofit.Builder()
                .baseUrl("http://10.0.3.2:8080/myUrl/rest/v1/")
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(httpClient.build())
                .build();

A user has a FavoriteSong, and a FavoriteSong has an Artist. My serializers are set up very similar, here is an example for the FavoriteSongSerializer.

public class FavoriteSongSerializer implements JsonSerializer<FavoriteSong> {
    @Override
    public JsonElement serialize(FavoriteSong src, Type typeOfSrc, JsonSerializationContext context) {
        Log.v("qwer", "serializingFavoriteSong");
        final JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("id", src.getId());
        jsonObject.add("song", context.serialize(src.getSong()));
        return jsonObject;
    }

}

Here is the User serializer:

public class UserSerializer implements JsonSerializer<User> {
    @Override
    public JsonElement serialize(User src, Type typeOfSrc, JsonSerializationContext context) {
        Log.v("qwer", "serializingUser");
        final JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("id", src.getId());
        jsonObject.add("favoriteSong", context.serialize(src.getFavoriteSong()));
        return jsonObject;
    }
}

The weird part is, both the FavoriteSong and Song serializers are called when I send my request (I can see the log statements), but the UserSerializer is not. Anyone know why this might be happening, or how I might troubleshoot?

/** Edit **/

So as a test I created a TestModel that just contains an id, created a serializer for it, registered a type adapter, and added it to my User model. And it also fails to call the TestModelSerializer (even though it serializes according to the default method).


Solution

  • So if register my User type adapter as:

    registerTypeAdapter(User.class, new UserSerializer())
    

    instead of:

    .registerTypeAdapter(Class.forName("io.realm.UserProxy"), new UserSerializer())
    

    the User serializer is called. I still have no idea why, but it works.