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

2

Gsonでシリアル化するための以前の回答で述べたようにRealmObject、適切なものJsonSerializerはGsonインスタンスに登録する必要があります。JsonSerializerフィールドの代わりにゲッターで動作する Gsonのユニバーサルの例を以下に示します。

まず、次のように使用するには、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 に答える