-
-
Save cmelchior/ddac8efd018123a1e53a to your computer and use it in GitHub Desktop.
// GSON can parse the data. | |
// | |
// Deserialization: | |
// Note there is a bug in GSON 2.3.1 that can cause it to StackOverflow when working with RealmObjects. | |
// To work around this, use the ExclusionStrategy below or downgrade to 1.7.1 | |
// See more here: https://code.google.com/p/google-gson/issues/detail?id=440 | |
// | |
// Serialization: | |
// <Type>RealmProxy objects are created by the Realm annotation processor. They are used to control | |
// access to the actual data instead of storing them in fields and it is therefore them we need to register a | |
// TypeAdapter for. | |
Gson gson = 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; | |
} | |
}) | |
.registerTypeAdapter(Class.forName("io.realm.PersonRealmProxy"), new PersonSerializer()) | |
.registerTypeAdapter(Class.forName("io.realm.DogRealmProxy"), new DogSerializer()) | |
.create(); | |
// Serialize a Realm object to a JSON string | |
String json = gson.toJson(realm.where(Person.class).findFirst()); |
package io.realm.example; | |
import io.realm.RealmObject; | |
public class Dog extends RealmObject { | |
private String name; | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
} |
package io.realm.examples; | |
import com.google.gson.JsonElement; | |
import com.google.gson.JsonObject; | |
import com.google.gson.JsonSerializationContext; | |
import com.google.gson.JsonSerializer; | |
import java.lang.reflect.Type; | |
import io.realm.examples.realmgridview.Dog; | |
public class DogSerializer implements JsonSerializer<Dog> { | |
@Override | |
public JsonElement serialize(Dog src, Type typeOfSrc, JsonSerializationContext context) { | |
final JsonObject jsonObject = new JsonObject(); | |
jsonObject.addProperty("name", src.getName()); | |
return jsonObject; | |
} | |
} |
package io.realm.example; | |
import io.realm.RealmList; | |
import io.realm.RealmObject; | |
public class Person extends RealmObject { | |
private String name; | |
private int age; | |
private Dog favoriteDog; | |
private RealmList<Dog> dogs; | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
public int getAge() { | |
return age; | |
} | |
public void setAge(int age) { | |
this.age = age; | |
} | |
public Dog getFavoriteDog() { | |
return favoriteDog; | |
} | |
public void setFavoriteDog(Dog favoriteDog) { | |
this.favoriteDog = favoriteDog; | |
} | |
public RealmList<Dog> getDogs() { | |
return dogs; | |
} | |
public void setDogs(RealmList<Dog> dogs) { | |
this.dogs = dogs; | |
} | |
} |
package io.realm.example; | |
import com.google.gson.JsonElement; | |
import com.google.gson.JsonObject; | |
import com.google.gson.JsonSerializationContext; | |
import com.google.gson.JsonSerializer; | |
import java.lang.reflect.Type; | |
public class PersonSerializer implements JsonSerializer<Person> { | |
@Override | |
public JsonElement serialize(Person src, Type typeOfSrc, JsonSerializationContext context) { | |
final JsonObject jsonObject = new JsonObject(); | |
jsonObject.addProperty("name", src.getName()); | |
jsonObject.addProperty("age", src.getAge()); | |
jsonObject.add("favoriteDog", context.serialize(src.getFavoriteDog())); | |
jsonObject.add("dogs", context.serialize(src.getDogs())); | |
return jsonObject; | |
} | |
} |
The more i use realm, the more reasons i keep finding not to use it.
Yes, you don't have to write boilerplate SQL but you introduce new boilerplate and workarounds.
@cmelchior this doesn't work with Realm-1.1.0 and Retrofit2-2.1.0. Not sure if to create issue for realm or retrofit
@cmelchior also experiencing this issue...
Update:
this is in fact working with realm 1.1.1; exactly as it is demonstrated. i was using my model class when registering the adapter instead of realm's proxy class for the model.
@ArthurSav meh, to serialize with GSON, just call gson.toJson(realm.copyFromRealm(realmObject));
@ArthurSav I find it incredibly creepy that I was thinking exactly the same thing right before reading your comment.....
gson.toJson(realm.copyFromRealm(realmObject)); return a JsonObject? How i can do that? @Zhuinden
copyFromRealm will return a unmanaged object/objects, so you can use it directly with no realm exception.
gson.toJson(realm.copyFromRealm(realmObject/realmObjects));
is a lazy function but it worked.
I am using this and it actually works with me:
Gson gson = new Gson();
String listString = gson.toJson(
items,
new TypeToken<ArrayList<Item>>() {}.getType());
try {
JSONArray jsonArray = new JSONArray(listString);
System.out.println(jsonArray.toString());
} catch (JSONException e) {
e.printStackTrace();
}
After tow days of bug resolve, i found this SIMPLE solution.
YourRealmObject realmObj = realm.where(YourRealmObject.class).findFirst(); if(realmObj != null) { realmObj = realm.copyFromRealm(realmObj); //detach from Realm, copy values to fields String json = gson.toJson(realmObj); }
if there's 100 model, then i have to make 100 type adapter.....
For those who still has troubles with serialization:
Your model:
Your UserSerializer:
Your method where you call e.g. retrofit interface:
Your Gson configuration:
profit.