【问题标题】:Retrofit and Realm access from another thread in Android从 Android 中的另一个线程进行改造和领域访问
【发布时间】:2015-05-25 11:04:02
【问题描述】:

我将 Realm 用于数据库服务,将 Retrofit 用于服务器服务。 我想从 Realm 获取数据并将其作为对象传递给 Retrofit,但出现以下错误:

     retrofit.RetrofitError: Realm access from incorrect thread. Realm objects can only be accessed on the thread they where created.
05-25 12:58:36.418   W/System.err﹕ at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:400)
05-25 12:58:36.418   W/System.err﹕ at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
05-25 12:58:36.418   W/System.err﹕ at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
05-25 12:58:36.418   W/System.err﹕ at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
05-25 12:58:36.418   W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
05-25 12:58:36.418   W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
05-25 12:58:36.423   W/System.err﹕ at retrofit.Platform$Android$2$1.run(Platform.java:142)
05-25 12:58:36.423   W/System.err﹕ at java.lang.Thread.run(Thread.java:856)
05-25 12:58:36.423   W/System.err﹕ Caused by: java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they where created.
05-25 12:58:36.423   W/System.err﹕ at io.realm.Realm.checkIfValid(Realm.java:192)
05-25 12:58:36.423   W/System.err﹕ at io.realm.DisabilitiesRealmProxy.isWheelchair(DisabilitiesRealmProxy.java:47)
05-25 12:58:36.423   W/System.err﹕ at io.realm.DisabilitiesRealmProxy.toString(DisabilitiesRealmProxy.java:238)
05-25 12:58:36.423   W/System.err﹕ at retrofit.RequestBuilder.setArguments(RequestBuilder.java:312)
05-25 12:58:36.423   W/System.err﹕ at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:298)
05-25 12:58:36.423   W/System.err﹕ ... 7 more

一切从这里开始:

if (ConnectionUtils.isConnectionToInternetEnabled(this)) {
        PlaceServerService.getPlaces("London", DatabaseAdapter.getDisabilities(this));
    }

调用这个方法:

public static void getPlaces(String city, Disabilities disabilities) {
    PlaceClient client = createService(PlaceClient.class);
    client.getPlaces(city, disabilities, new Callback<PlaceResponse>() {

        @Override
        public void success(PlaceResponse placeResponse, Response response) {
            EventBus.getDefault().post(placeResponse.getPlaces());
        }

        @Override
        public void failure(RetrofitError error) {
            error.printStackTrace();
        }
    });
}

和这个接口:

@FormUrlEncoded
@POST("/places/city")
void getPlaces(@Field("city") String city,
               @Field("disabilities") Disabilities disabilities,
               Callback<PlaceResponse> callback);

我没看到,这里哪里有这个线程问题?我只是将对象传递给 Retrofit 方法。也许问题在于Disabilities 对象扩展了RealmObject

编辑:

但是,这个解决方案有效,为什么?

if (ConnectionUtils.isConnectionToInternetEnabled(this)) {
        Disabilities disabilities = DatabaseAdapter.getDisabilities(this);
        Disabilities disability = new Disabilities(
                disabilities.isWheelchair(),
                disabilities.isBlind(),
                disabilities.isDeaf(),
                disabilities.isOtherMovement());
        PlaceServerService.getPlaces("London", disability);
    }

【问题讨论】:

  • 要打破这个领域的限制,你可以参考这篇文章stackoverflow.com/questions/26602258/…。它显示了一种包装器类型的实现,可将您的应用程序从不正确的线程异常中的领域访问中释放出来
  • 我有同样的问题。谢谢你的提问。
  • @savepopulation 没问题的朋友

标签: android multithreading retrofit realm


【解决方案1】:

是的 Disabilities 扩展了 RealmObject 并且是 Realm 的一部分。你可以做的是创建一个新对象:

Disabilities disabilities = new Disabilities();

然后将Disabilities 中的内容放入新对象中。这是可行的,因为这个对象还没有在Realm 中。

【讨论】:

  • 我这样做了,它可以工作(见编辑),但是它有点解决方法,我很好奇是否有更好的解决方案。如果不是,这是一个正确的答案。
  • @kodw 我还没有找到其他解决方案。 Here 是从Realm 复制方法的功能请求。实现该功能请求后,您可以以更简单的方式处理此问题。另外我真的不知道改造是如何工作的,我假设它将对象转换为JSON。也许您可以要求String 而不是Disabilities 并使用GSONDisabilities 转换为String
猜你喜欢
  • 1970-01-01
  • 2017-03-22
  • 2017-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
相关资源
最近更新 更多