2017-02-16 3 views
0

Ich habe ein kleines Problem mit meinen benutzerdefinierten Serialisierer arbeiten mit Retrofit, Realm und Gson. Hier bin ich Registrierung Typ Adapter für meine drei Klassen:Android Retrofit + Realm + Gson: Serializer nicht genannt

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(); 

Ein Benutzer hat eine FavoriteSong und ein FavoriteSong hat einen Künstler. Meine Serializer sind sehr ähnlich aufgebaut, hier ein Beispiel für den FavoriteSongSerializer. Hier

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; 
    } 

} 

ist der Nutzer 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; 
    } 
} 

Der seltsame Teil ist, sowohl die FavoriteSong und Song Serializer aufgerufen werden, wenn ich meine Anfrage senden (I die Log-Anweisungen sehen), aber die UserSerializer ist nicht. Wer weiß, warum dies passieren könnte oder wie ich Fehler beheben könnte?

/** ** Bearbeiten/

So als Test ich eine TestModel erstellt, die nur eine ID enthält, erstellt einen Serializer für sie, eine Art Adapter registriert, und es zu meinem User-Modell. Und es kann den TestModelSerializer auch nicht aufrufen (obwohl er gemäß der Standardmethode serialisiert wird).

+0

Ich bin Realm nicht vertraut, aber das Problem könnte sein, dass z. UserSerializer benötigt einen Benutzer, während Sie den Adapter für die Klasse io.realm registrieren.UserProxy –

+4

Haben Sie [diese Antwort] (http://stackoverflow.com/a/42044320/3503855) überprüft? Es bietet eine viel einfachere Möglichkeit zur Umgehung der Gson + Realm Inkompatibilität. – AnixPasBesoin

+0

Das wird meinem spezifischen Problem leider nicht helfen (Ich fand eine Lösung unten), aber definitiv gut, um diesen Post für irgendjemanden Retrofit-Gson Probleme zu zeigen, ich habe das gleiche Szenario vor ein paar Wochen behandelt und es hat eine Weile gedauert finde heraus, was vor sich geht. – jwBurnside

Antwort

0

So registrieren, wenn mein Usertyp Adapter als:

registerTypeAdapter(User.class, new UserSerializer()) 

statt:

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

der Benutzer Serializer aufgerufen wird. Ich habe immer noch keine Ahnung warum, aber es funktioniert.

0

Versuchen mit registerTypeHierarchyAdapter statt registerTypeAdapter:

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

EDIT:

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()) 
+0

Ich versuchte das mit den gleichen Ergebnissen. – jwBurnside

+0

Wenn Sie nur UserSerializer registrieren, funktioniert es? Bitte fügen Sie den Code für diesen Serializer hinzu –

+0

Ich habe den Benutzer-Serializer hinzugefügt. Ich kann nicht "nur" den Benutzer-Serializer testen, weil Gson mit einem Fit aufgrund der FavoriteSong- und Song-Referenzen wirft. – jwBurnside

Verwandte Themen