2015-05-19 26 views
12

Tôi có API Retrofit sau:Retrofit POST Realm đối tượng

@POST("/payments")  
Observable<Response> saveCreditCard(@Body CreditCard creditCard) 

CreditCard là một RealmObject.

Khi tôi cố gắng sử dụng phương pháp API của tôi:

CreditCard card = realm.createObject(CreditCard.class); 
card.setWhateverField(...); 
... 
mApi.saveCreditCard(card) 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(...); 

tôi nhận được lỗi sau:

> retrofit.RetrofitError: com.fasterxml.jackson.databind.JsonMappingException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they where created. 
System.err﹕ at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:400) 
System.err﹕ at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220) 
System.err﹕ at retrofit.RestAdapter$RestHandler$1.invoke(RestAdapter.java:265) 
System.err﹕ at retrofit.RxSupport$2.run(RxSupport.java:55) 
System.err﹕ at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 
System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
System.err﹕ at retrofit.Platform$Android$2$1.run(Platform.java:142) 
System.err﹕ at java.lang.Thread.run(Thread.java:818) 
System.err﹕ Caused by: java.lang.AssertionError: com.fasterxml.jackson.databind.JsonMappingException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they where created. 

Tôi giả định Retrofit mà là làm serialization để JSON trên io() lên lịch, vì thế lỗi.

Có ai có đề xuất nào về cách khắc phục sự cố luồng của Realm không?

+0

Dường như bạn phải có mô hình cho Realm và mô hình thứ hai để trang bị thêm và có lớp để "chuyển đổi" đối tượng này với nhau. – Divers

+0

Chúng tôi có hơn 50 mô hình, vì vậy đó không thực sự là một giải pháp. –

+0

Tôi hiểu, nhưng cơ hội lớn đó chỉ là giải pháp. – Divers

Trả lời

7

CẬP NHẬT

Realm thêm hỗ trợ để tách đối tượng bằng cách sử dụng realm.copyFromRealm(yourObject, depthLevel)

CreditCard creditCard = realm.createObject(CreditCard.class); 
card.setWhateverField(...); 
... 

final int relationshipsDepthLevel = 0; 
creditCard = realm.copyFromRealm(creditCard, relationshipsDepthLevel); 
mApi.saveCreditCard(temporaryCard) 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(...); 

PHẢN ĐỐI ĐÁP sau:

Tôi tìm thấy một workaround mà đòi hỏi 2 dòng thêm mã, và một bước tuần tự thêm.

@Inject 
ObjectMapper mObjectMapper; // I use Dagger2 for DI 

.... 

CreditCard creditCard = realm.createObject(CreditCard.class); 
card.setWhateverField(...); 
... 
// I use Jackson's ObjectMapper to "copy" the original creditCard 
// to a new temporary instance that has not been tied to a Realm. 
String json = mObjectMapper.writeValueAsString(creditCard); 
PaymentCreditCardDataView temporaryCard = mObjectMapper 
        .reader(PaymentCreditCardDataView.class) 
        .readValue(json); 
mApi.saveCreditCard(temporaryCard) 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(...); 

Nhược điểm là tôi có thêm một đối tượng và thêm một bước tuần tự hóa + deserialisation, trên chuỗi giao diện người dùng. Nó sẽ là ok nếu tôi có đối tượng với kích thước hợp lý.

+1

giải pháp thông minh – Loki

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