2015-05-19 6 views
12

У меня есть следующая ДООСНАСТКА API:RETROFIT POST Realm объект

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

CreditCard является RealmObject.

Когда я пытаюсь использовать мой метод API:

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

Я получаю следующее сообщение об ошибке:

> 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. 

Я предполагаю, что RETROFIT делает сериализацию для JSON на io() планировщика, следовательно, Ошибка.

Есть ли у кого-нибудь какие-либо предложения, как я могу преодолеть проблему Threading Threading?

+0

Кажется, у вас должна быть модель для Realm и вторая модель для Retrofit и иметь класс для «преобразования» этих объектов друг в друга. – Divers

+0

У нас более 50 моделей, так что это не решение. –

+0

Я понимаю, но большой шанс, что это только решение. – Divers

ответ

7

UPDATE

Realm добавлена ​​поддержка отделяться объектов с помощью 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(...); 

DEPRECATED ОТВЕТ следующим образом:

Я нашел обходной путь, который требует 2 дополнительных строк кода, и дополнительный шаг сериализации.

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

Недостатком является то, что у меня есть дополнительный объект и дополнительные сериализации + десериализация шаг, в потоке пользовательского интерфейса. Это должно быть нормально, если у меня есть объекты с разумными размерами.

+1

умное решение – Loki

Смежные вопросы