realm-java: Illegal State: Object is no longer valid to operate on. Was it deleted by another thread?

After I delete an item from RealmResults, the last item stay in the first position,and I continued to delete, the app crashed. The issue is “Illegal State: Object is no longer valid to operate on. Was it deleted by another thread?”

The following is my code :

int position = viewHolder.getAdapterPosition();
List<User> usersInDb = realm.where(User.class).findAll();
for (User user : usersInDb) {
    Log.i(TAG, user.getAvatarUrl());
}
Log.i(TAG, "=====================");
userList.remove(position);
userAdapter.notifyItemRemoved(position);
userAdapter.notifyItemRangeChanged(position, userAdapter.getItemCount());
realm.executeTransaction(realm1 -> usersInDb.remove(position));
List<User> usersInDbAfterRemove = realm.where(User.class).findAll();
for (User user : usersInDbAfterRemove) {
    Log.i(TAG, user.getAvatarUrl());
}
Log.i(TAG, "=====================");

Thank you.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 15 (6 by maintainers)

Most upvoted comments

This typically happens if you’re not using RealmResults+RealmChangeListener to update your RecyclerView, but you map managed RealmObjects into an ArrayList which doesn’t update, so this leaves you in a state where your ArrayList can contain a managed but deleted item which you access so your app crashes.

Solution: use RealmChangeListener to listen for changes

Answer: I got these errors , and While the solution was simple. 1- java.lang.IllegalStateException: Object is no longer managed by Realm. Has it been deleted? 2- ThrowingException 8, Object is no longer valid to operate on. Was it deleted by another thread?, . 11-19 00:19:02.146 21759-21932/zeroturnaround.org.jrebel4androidgettingstarted E/REALM_JNI: Exception has been throw: Object is no longer valid to operate on. Was it deleted by another thread?

The Bad Code: if (subServiceId != null && !subServiceId.isEmpty()) { mSubServiceModelDelete.setDeleted(true); realm.copyToRealmOrUpdate(mSubServiceModelDelete); } else {

                mSubServiceModelDelete.deleteFromRealm();
                Log.d("TAG", "Service is Deleted from database.." + mSubServiceModelDelete.getSubservicesSubservicename());
            }

The Good and Error Free Code: if (subServiceId != null && !subServiceId.isEmpty()) { mSubServiceModelDelete.setDeleted(true); realm.copyToRealmOrUpdate(mSubServiceModelDelete); } else { Log.d(“TAG”, “Service is Deleted from database…” + mSubServiceModelDelete.getSubservicesSubservicename()); mSubServiceModelDelete.deleteFromRealm(); }

So that was the Solution For This Error, This Was Error, as i was accessing deleted object after deleting it. LOL Happy Coding 😃 😃

@beeender OK, Thank you for your reply. via your description, I have realized I made a mistake . And I corrected my code to the following, and it worked correctly.

1 realm dynamic changed, I use RealmResults as data source, I don’t need to deal with data source, when data source changes, I notifyDataSetChanged directly.

realm = Realm.getDefaultInstance();
realmResults = realm.where(User.class).findAll();
Log.i(TAG, String.valueOf(realmResults.size()));//size is 0 
userAdapter = new UserAdapter(realmResults, this);
......
Observable.merge(getObservables(users))
.subscribe(users2 -> {
    circularProgressBar.setVisibility(View.GONE);
    userAdapter.notifyDataSetChanged();//don't need to deal with data source, notifyDataSetChanged directly
}, Throwable::printStackTrace);

2 The same reason , when I delete an item, dealing with RealmResult is equal to deal with List and SQLite before.

int position = viewHolder.getAdapterPosition();
realm.executeTransaction(realm1 -> realmResults.remove(position));
userAdapter.notifyItemRemoved(position);
userAdapter.notifyItemRangeChanged(position, userAdapter.getItemCount());

Thank you very much!