问题描述
我与Retrofit,Realm和Gson一起使用的自定义序列化器存在一些问题。 在这里,我为三个类注册类型适配器:
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();
用户拥有一首收藏歌曲,而一首收藏歌曲具有艺术家。 我的序列化器的设置非常相似,这是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;
}
}
这是用户序列化器:
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;
}
}
奇怪的是,我发送请求时会同时调用FavoriteSong和Song序列化程序(我可以看到日志语句),而UserSerializer却没有。 任何人都知道为什么会发生这种情况,或者我如何解决问题?
/ **编辑** /
因此,作为测试,我创建了一个仅包含id的TestModel,为其创建了序列化器,注册了类型适配器,并将其添加到我的User模型中。 而且它也无法调用TestModelSerializer(即使它根据默认方法进行序列化)。
1楼
尝试使用registerTypeHierarchyAdapter
而不是registerTypeAdapter
:
.registerTypeHierarchyAdapter(Class.forName("io.realm.UserProxy"), new UserSerializer())
编辑:
builder
.setExclusionStrategies(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getDeclaringClass().equals(RealmObject.class);
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
})
.registerTypeAdapter(Class.forName("io.realm.UserProxy"), new UserSerializer())
.registerTypeAdapter(Class.forName("io.realm.FavoriteSongProxy"), new FavoriteSongSerializer())
.registerTypeAdapter(Class.forName("io.realm.ArtistProxy"), new ArtistSerializer())
2楼
因此,如果将我的用户类型适配器注册为:
registerTypeAdapter(User.class, new UserSerializer())
代替:
.registerTypeAdapter(Class.forName("io.realm.UserProxy"), new UserSerializer())
用户序列化器被调用。 我仍然不知道为什么,但是可以。