Android 中另一个线程的 Retrofit 和 Realm 访问
Retrofit and Realm access from another thread in Android
我将 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.access0(RestAdapter.java:220)
05-25 12:58:36.418 W/System.err﹕ at retrofit.RestAdapter$RestHandler.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.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
object extends 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);
}
是的 Disabilities
扩展了 RealmObject
并且是 Realm
的一部分。您可以做的是创建一个新对象:
Disabilities disabilities = new Disabilities();
然后将 Disabilities
中的内容放入新对象中。这是有效的,因为这个对象还不在 Realm
中。
我将 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.access0(RestAdapter.java:220)
05-25 12:58:36.418 W/System.err﹕ at retrofit.RestAdapter$RestHandler.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.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
object extends 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);
}
是的 Disabilities
扩展了 RealmObject
并且是 Realm
的一部分。您可以做的是创建一个新对象:
Disabilities disabilities = new Disabilities();
然后将 Disabilities
中的内容放入新对象中。这是有效的,因为这个对象还不在 Realm
中。