2015-05-19 6 views
12

Ich habe folgenden NACHRÜST API:NACHRÜST POST Realm Objekt

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

CreditCard ist ein RealmObject.

Wenn ich versuche, meine API-Methode zu verwenden:

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

ich die folgende Fehlermeldung erhalten:

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

Ich gehe davon aus, dass NACHRÜST die Serialisierung JSON auf dem io() Scheduler tut, damit der Fehler.

Hat jemand einen Vorschlag, wie ich Realms Threading-Problem überwinden kann?

+0

Scheint müssen Sie Modell für Realm und zweites Modell für Retrofit haben und Klasse haben, um diese Objekte zu "konvertieren". – Divers

+0

Wir haben über 50 Modelle, also ist das nicht wirklich eine Lösung. –

+0

Ich verstehe, aber große Chance, dass es nur eine Lösung ist. – Divers

Antwort

7

UPDATE

Realm zusätzliche Unterstützung Objekte lösen von 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 ANTWORT mit folgt:

fand ich eine Abhilfe, die 2 zusätzliche Zeilen Code erfordert, und ein zusätzlicher Serialisierungsschritt.

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

Der Nachteil ist, dass ich eine zusätzliche Aufgabe und ein zusätzliches Serialisierung + Deserialisation Schritt, auf dem UI-Thread. Es sollte in Ordnung sein, wenn ich Objekte mit vernünftigen Größen habe.

+1

clevere Lösung – Loki

Verwandte Themen