我有以下RETROFIT API:
@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()
进行序列化,因此出错。
有没有人有任何建议我如何克服Realm的线程问题?
答案 0 :(得分:7)
更新
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(...);
弃用的答案如下:
我找到了一种解决方法,需要额外增加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(...);
缺点是我在UI线程上有一个额外的对象和一个额外的序列化+反序列化步骤。如果我有合理尺寸的物体,应该没问题。