19

我的目标是将使用 GSON 实例化的对象持久化到使用 realm 的数据库中

我的问题如下:

  • 我可以使用 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 可能会起作用。

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

4

3 回答 3

13

来自 Realm 的 Emanuele。

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

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

于 2014-10-09T10:02:34.103 回答
2

正如之前在使用 Gson 进行序列化的答案中所说的那样,应该在 Gson 实例中注册RealmObject适当的。JsonSerializer下面是一个通用JsonSerializer的 Gson 示例,它使用 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);
            }
        }
    }
}
于 2015-12-21T08:11:24.990 回答
0

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

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

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

检查此答案以获取更多详细信息和其他解决方案。

于 2017-02-18T00:59:26.933 回答