2014-10-09 126 views
18

我的目标是将用GSON实例化的对象保存到数据库合并Realm对象和Gson对象

我的问题是这样的:

  • 我可以实例与GSON一个对象,所以GSON通吃的特性, 的护理,但那么它不会被持久化到数据库

  • 我可以使用Realm实例化一个对象,但是我必须填写所有属性的设置器。

在我的OnCreate,这部分是这两种方法

//delete previous realm file 
Realm.deleteRealmFile(this); 

//gson instance 
Gson gson = new Gson(); 

//realm instance 
realm = Realm.getInstance(this); 

同**我的类的名称是Vacature **

信息:我知道下面的代码需要被内:

realm.beginTransaction(); 

// code here 

realm.commitTransaction(); 

选项1:

//get class with gson 
Vacature vacatureGson = gson.fromJson(jsonString, Vacature.class); 

这是行不通的,因为你必须使用

Class instance = realm.createObject(Class.class); // Create a new object 

选项2,实例化一个境界对象:

//get instance with gson 
Vacature vacatureGson = gson.fromJson(jsonString, Vacature.class); 
//make instance with realm 
Vacature realmVacature = realm.createObject(Vacature.class); 
realmVacature = vacatureGson; 

这是行不通的,因为这不是一个正确的方法将所有属性从一个对象复制到另一个对象。 如果有一种将gsonObject的所有属性复制到realmObject的好方法, 选项2可能有效。

关于如何解决这个难题的任何想法?

回答

13

Emanuele from Realm here。

现在的解决方案是不理想的,并在其中一个例子,提出:https://github.com/realm/realm-java/blob/master/examples/gridViewExample/src/main/java/io/realm/examples/realmgridview/GridViewExampleActivity.java

我们正在努力使经验的方式更流畅!

+1

我正在研究这个例子:)你到目前为止做的很好!如果我理解正确,在这个例子中你手动设置了setters。 与此同时,我正在寻找一个坚实的deepcopy-all-the-properties解决方案的互联网:) – TomCB 2014-10-09 10:05:36

+0

请让我们更新关于这个问题。如果您找不到解决方案,请告诉社区!我们一起可以解决问题! – TomCB 2014-10-13 10:58:10

+2

我对如何解决这个问题有一个坚实的想法。我会尽力开发一个概念证明。 – Emanuelez 2014-10-13 12:18:14

2

正如之前在Gson实例中注册序列号为RealmObject的答案中所述,适当的JsonSerializer应该被注册。在我的例子中,Gson的通用JsonSerializer与getters而不是字段一起使用。

首先,它应该与GSON为了使用这样注册:

@NonNull private static Gson createGson() { 
      GsonBuilder gsonBuilder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation(); 
      try {   
        gsonBuilder.registerTypeAdapter(Class.forName("io.realm.<YourClassName1>RealmProxy"), Serializer.newInstance(<YourClassName1>.class)); 
        gsonBuilder.registerTypeAdapter(Class.forName("io.realm.<YourClassName2>RealmProxy"), Serializer.newInstance(<YourClassName2>.class)); 
        ... 
       } catch (ClassNotFoundException e) { 
        e.printStackTrace(); 
       } 

     return gsonBuilder.create(); 
    } 

然后它可以从任何像这样的RealmObject来源(甚至由境界创建)类得到JSON:

public class MessageModel extends RealmObject { ... } 
String json = createGson().toJson(messageModelInstance); 

而且你可以复制MessageModel这样的:

MessageModel src= ...; 
MessageModel dst= ...; 

Serializer.newInstance(MessageModel.class).copy(src, dst); 

这里Serializer

public class Serializer<T> implements JsonSerializer<T> { 

    private Class<T> clazz; 
    private Serializer(Class<T> clazz) {this.clazz = clazz;} 

    @NonNull 
    public static <T> Serializer<T> newInstance(Class<T> clazz) {return new Serializer<T>(clazz);} 

    @Override 
    public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) { 

     final JsonObject jsonObject = new JsonObject(); 

     Field[] fields = clazz.getDeclaredFields(); 
     for (Field f : fields) { 
      if (f.isAnnotationPresent(Expose.class)) try { 

       String name = f.getName(); 
       String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1); 
       Method method = src.getClass().getMethod(methodName); 
       Object o = method.invoke(src); 

       if (o instanceof String) { 
        jsonObject.addProperty(name, (String) o); 
       } 
       else if (o instanceof Number) { 
        jsonObject.addProperty(name, (Number) o); 
       } 
       else if (o instanceof Boolean) { 
        jsonObject.addProperty(name, (Boolean) o); 
       } 
       else if (o instanceof Character) { 
        jsonObject.addProperty(name, (Character) o); 
       } 

      } catch (InvocationTargetException e) { 
       e.printStackTrace(); 
      } catch (NoSuchMethodException e) { 
       e.printStackTrace(); 
      } catch (IllegalAccessException e) { 
       e.printStackTrace(); 
      } 
     } 

     return jsonObject; 
    } 

    public <T> void copy(T src, T dst) { 

     Field[] fields = clazz.getDeclaredFields(); 
     for (Field f : fields) { 
      if (f.isAnnotationPresent(Expose.class)) try { 

       String name = f.getName(); 

       String getterName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1); 
       String setterName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1); 
       Method getter = clazz.getMethod(getterName); 
       Method setter = clazz.getMethod(setterName, f.getType()); 

       setter.invoke(dst, getter.invoke(src)); 

      } catch (Exception e) { 
       e.printStackTrace(); 
       checkState(false); 
      } 
     } 
    } 
} 
+0

什么是checkstate? – Olayinka 2016-01-20 21:36:44

+0

对不起,你的意思是?你能解释你的问题吗? – 2016-01-22 15:54:43

+0

这很好用。另一件需要记住的事情是,只有在创建RealmObject的同一个线程中调用它才会起作用,否则它将抛出Realm异常。如果你的模型类不使用这个注解,也可以删除if(f.isAnnotationPresent(Expose.class))。 – velval 2016-09-08 07:41:24

0

这可以用一行代码来实现。

在管理RealmObject内存获取副本,并把它传递给GSON

String jsonVacature = new Gson().toJson(realm.copyFromRealm(vacature)); 

检查this answer的详细信息和其他的解决方案。