filipp.kowalski
filipp.kowalski

Reputation: 5605

Retrofit and Realm access from another thread in Android

I am using Realm for database service and Retrofit for server service. I want to get data from Realm and pass it as object to Retrofit, but I get following error :

     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

It all starts here :

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

Which calls this method :

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();
        }
    });
}

And interface to this :

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

I don't see, where it has this thread issue here? I am just passing object to the Retrofit method. Maybe the problem is that Disabilities object extends RealmObject?

EDIT :

However, this solution works, why?

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);
    }

Upvotes: 4

Views: 1878

Answers (1)

Kevin van Mierlo
Kevin van Mierlo

Reputation: 9794

Yeah Disabilities extends RealmObject and is part of the Realm. What you could do is create a new object:

Disabilities disabilities = new Disabilities();

And then put the content that's inside the Disabilities in your new object. This works because this object is not in Realm yet.

Upvotes: 3

Related Questions