0

I want to post each RealmResults data to a REST endpoint, and want to delete its data if sending is success.

Running following code, success sending but fail to delete.
I tried to use target.deleteFromRealm() in Response() but IllegalStateException occurred.

java.lang.IllegalStateException: Realm access from incorrect thread. 
        Realm objects can only be accessed on the thread they were created.

How can I delete target? (using Realm Java 3.1.2 and Retrofit 2.2.0)

RealmResults<Model> results = realm.where(Model.class).findAll();
for ( final Model target: results ){
    Call<Void> task = restInterface.post(gson.toJson(target));
    task.enqueue( new CallBack<Void>(){
        @Override
        public void onResponse(Call<Void> call, Response<Void> response) {
            // ?? how to delete target from realm ??
        }

        @Override
        public void onFailure(Call<Void> call, Throwable t) {
            // do nothing
        }
    });
}
user3752013
  • 189
  • 1
  • 8
  • "I tried to use deleteFromRealm() but fail." define "fail". – njzk2 Apr 18 '17 at 18:15
  • Realm objects are not copied so you are accessing the same objects; have you tried updating the objects that have been sent successfully like a column called status set to synced; then later when done, delete them? – Eenvincible Apr 18 '17 at 18:17

1 Answers1

0

It is the same as removing items for normal ArrayLists. That is not allowed either and will throw ConcurrentModificationException.

Also I would suggest not to send items one by one to server, but collect them into array and pass all the data in one request.

To collect all data into ArrayList you can use

RealmResults<Model> results = realm.where(Model.class).findAll();
ArrayList<Model> list = new ArrayList(results);

And then try to send data like this:

Call<Void> task = restInterface.post(gson.toJson(list));
    task.enqueue( new CallBack<Void>(){
        @Override
        public void onResponse(Call<Void> call, Response<Void> response) {
            // As a result all data will be uploaded in the same one batch and you can safely clear the db
             results.deleteAllFromRealm();
        }

        @Override
        public void onFailure(Call<Void> call, Throwable t) {
            // do nothing
        }
    });
Bogdan Ustyak
  • 5,639
  • 2
  • 21
  • 16
  • "ConcurrentModificationException" only if the callback is called while the loop is still active – njzk2 Apr 18 '17 at 18:14
  • 1
    `gson.toJson(list)` nothing the in OP's post suggests that the endpoint also accepts a list, rather than individual items – njzk2 Apr 18 '17 at 18:15
  • @njzk2 That's true, and this is only my suggestion (to use one request instead of many of them) – Bogdan Ustyak Apr 18 '17 at 18:18