2014-10-09 33 views
18

Mục tiêu của tôi là tồn tại một đối tượng được khởi tạo với GSON với cơ sở dữ liệu có địa chỉ.Hợp nhất đối tượng Realm & đối tượng Gson

Vấn đề của tôi là như sau:

  • tôi có thể tạo một đối tượng với GSON, vì vậy GSON sẽ chăm sóc của tất cả các tài sản, nhưng sau đó nó sẽ không được tiếp tục tồn để db

  • Tôi có thể khởi tạo một đối tượng với Realm, nhưng sau đó tôi phải điền vào tất cả các setters cho các thuộc tính.

Trong onCreate của tôi, phần này là như nhau cho cả hai phương pháp

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

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

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

** Tên của lớp học của tôi là Vacature **

Thông tin: Tôi biết rằng đoạn mã sau cần phải được bên trong:

realm.beginTransaction(); 

// code here 

realm.commitTransaction(); 

Lựa chọn 1:

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

này sẽ không làm việc bởi vì bạn phải tạo một đối tượng lĩnh vực bằng cách sử dụng

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

Phương án 2:

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

này sẽ không làm việc vì đây không phải là một cách thích hợp để sao chép tất cả các thuộc tính từ một đối tượng này sang đối tượng khác. Nếu có một cách tốt để sao chép tất cả các thuộc tính từ gsonObject sang realmObject, tùy chọn 2 có thể hoạt động.

Bất kỳ ý tưởng nào về cách giải quyết câu đố này?

Trả lời

13

Emanuele từ Realm ở đây.

Ngay bây giờ giải pháp là tối ưu và được trình bày trong một trong những ví dụ: https://github.com/realm/realm-java/blob/master/examples/gridViewExample/src/main/java/io/realm/examples/realmgridview/GridViewExampleActivity.java

Chúng tôi đang làm việc để làm cho kinh nghiệm cách mượt mà!

+1

Tôi đã nhìn vào ví dụ mà :) bạn đang làm một công việc tuyệt vời cho đến nay! Nếu tôi hiểu chính xác, trong ví dụ này, bạn cài đặt thủ công. Trong khi đó, tôi đang tìm kiếm trên Internet cho một deepcopy-all-the-tính chất dung dịch rắn :) – TomCB

+0

Hãy giữ cho chúng tôi cập nhật về vấn đề này. Nếu bạn không thể tìm thấy giải pháp, hãy cho cộng đồng biết! Cùng nhau chúng ta có thể làm việc nó ra! – TomCB

+2

Tôi có một ý tưởng vững chắc về cách giải quyết vấn đề này. Tôi sẽ cố gắng phát triển một bằng chứng về khái niệm càng sớm càng tốt. – Emanuelez

2

Như đã được nêu trong các câu trả lời trước cho tuần tự RealmObject với Gson, thích hợp JsonSerializer phải được đăng ký tại trường hợp Gson. Dưới đây là ví dụ về một số phổ dụng JsonSerializer cho Gson hoạt động với getters thay vì trường.

Thứ nhất, nó phải được đăng ký với Gson để sử dụng như thế này:

@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(); 
    } 

Và sau đó nó có thể để có được JSON từ bất kỳ lớp RealmObject có nguồn gốc từ (và thậm chí tạo ra bởi Realm) như thế này:

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

Và bạn có thể sao chép MessageModel như thế này:

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

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

Và đây 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 là gì ?? – Olayinka

+0

Xin lỗi, ý bạn là gì? Bạn có thể giải thích câu hỏi của bạn được không? –

+0

Công trình này tuyệt vời. Một điều cần lưu ý là điều này sẽ chỉ hoạt động nếu được gọi trong cùng một Thread mà RealmObject được tạo ra nếu không nó sẽ ném các ngoại lệ của Realm. Cũng có thể loại bỏ nếu (f.isAnnotationPresent (Expose.class)) nếu các lớp mô hình của bạn không sử dụng chú thích này. – velval

0

này có thể đạt được với một dòng mã.

Nhận một bản sao trong bộ nhớ của RealmObject quản lý và vượt qua nó để Gson

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

Kiểm tra this answer để biết thêm chi tiết và các giải pháp khác.

Các vấn đề liên quan