【问题标题】:Merging Realm object & Gson object合并 Realm 对象和 Gson 对象
【发布时间】:2014-12-04 04:33:57
【问题描述】:

我的目标是将使用 GSON 实例化的对象保存到具有领域的数据库中

我的问题如下:

  • 我可以使用 GSON 实例化一个对象,因此 GSON 会处理所有属性, 但它不会被持久化到 db

  • 我可以用 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 可能有效。

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

【问题讨论】:

    标签: java android gson realm


    【解决方案1】:

    来自 Realm 的 Emanuele。

    目前解决方案不是最理想的,并在以下示例之一中提供:https://github.com/realm/realm-java/blob/master/examples/gridViewExample/src/main/java/io/realm/examples/realmgridview/GridViewExampleActivity.java

    我们正在努力使体验更加流畅!

    【讨论】:

    • 我正在研究那个例子 :) 到目前为止你做得很好!如果我理解正确,在此示例中您手动设置设置器。与此同时,我正在互联网上寻找可靠的 deepcopy-all-the-properties 解决方案:)
    • 请及时通知我们这个问题。如果您找不到解决方案,请让社区知道!我们可以一起解决!
    • 我对如何解决这个问题有一个可靠的想法。我会尽快开发概念验证。
    • 嗨@Emanuelez,只是想知道这方面是否有任何更新?或者有什么地方可以检查更新吗?谢谢!
    • JSON 对我们来说是一个非常热门的话题。你可以在this PRthis document看到进度
    【解决方案2】:

    正如之前在使用 Gson 序列化 RealmObject 的答案中所说,应在 Gson 实例中注册适当的 JsonSerializer。下面是 Gson 的通用 JsonSerializer 示例,它使用 getter 而不是字段。

    首先,它应该在 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 派生(甚至由 Realm 创建)的类中获取 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);
                }
            }
        }
    }
    

    【讨论】:

    • 什么是检查状态??
    • 对不起,你是什么意思?你能解释一下你的问题吗?
    • 这很好用。要记住的另一件事是,这仅在创建 RealmObject 的同一线程中调用时才有效,否则它将引发 Realm 异常。如果您的模型类不使用此注释,也可以删除 if (f.isAnnotationPresent(Expose.class))。
    【解决方案3】:

    这可以通过一行代码来实现。

    在内存中获取托管 RealmObject 的副本并将其传递给 Gson

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

    查看this answer 了解更多详情和其他解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-26
      • 2016-03-09
      • 2016-04-30
      相关资源
      最近更新 更多