Closed dobby closed 9 years ago
Hi @dobby I tried to reproduce your code and couldn't. I tried using the below activity. Does your code differ from that?
public class ExampleActivity extends Activity {
private Realm realm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_realm_basic_example);
realm = Realm.getInstance(this);
realm.addChangeListener(new RealmChangeListener() {
@Override
public void onChange() {
int size = realm.allObjects(Cat.class).size();
Log.e("REALM", "" + size);
}
});
new Thread(new Runnable() {
@Override
public void run() {
Realm realm = Realm.getInstance(getBaseContext());
realm.beginTransaction();
realm.createObject(Cat.class);
realm.commitTransaction();
realm.close();
}
}).start();
}
@Override
protected void onDestroy() {
super.onDestroy();
realm.close();
}
}
I've just run into the same issue. After a bit of head-scratching I've managed to isolate the cause a little more.
If you have just a single a Realm on the main thread with a change listener attached, then it works fine. The problem occurs after you create a second Realm on the main thread, and then close it. The first realm stops receiving change events.
Run the following as an example (adapted form @cmelchior 's code above). I have noticed that the log output does not occur with this code:
public class ExampleActivity extends Activity {
private Realm realm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_realm_basic_example);
realm = Realm.getInstance(this);
realm.addChangeListener(new RealmChangeListener() {
@Override
public void onChange() {
int size = realm.allObjects(Cat.class).size();
Log.e("REALM", "" + size);
}
});
final Realm anotherRealmOnTheMainThread = Realm.getInstance(this);
anotherRealmOnTheMainThread.close();
new Thread(new Runnable() {
@Override
public void run() {
Realm realm = Realm.getInstance(getBaseContext());
realm.beginTransaction();
realm.createObject(Cat.class);
realm.commitTransaction();
realm.close();
}
}).start();
}
@Override
protected void onDestroy() {
super.onDestroy();
realm.close();
}
}
I think that the issue could be fixed pretty easily. The problem is in these few lines in the Realm.close
method: https://github.com/realm/realm-java/blob/master/realm/src/main/java/io/realm/Realm.java#L198-L200
The Realm's handler is being removed even when there are still active references to the Realm object. Perhaps it's just as simple as changing it to the following:
if (handler != null && refCount <= 0){
removeHandler(handler);
}
I'm not familiar enough with the code to know if this will have any other consequences, so I'm not confident enough to make a pull request. But this should point in the right direction at least.
Hi @denley
I am glad you reproduced the error because I tried the other day and could not recreate the problem in a small sample project.
@denley Thank you for the code. You are absolute correct. The handler was getting removed to soon. It has been fixed in this PR: https://github.com/realm/realm-java/pull/753
Fix has been merged into master. Thanks for the bug report.
When performing a realm.commitTransaction(); inside a thread the realm is not updated until the application is restarted. So the changes are persisted but not visible in my application when i query them from the main ui thread. This bug was not present in the previous version 0.75.
Example:
This code sent a onChange event in version (0.75) in my ui thread but doesn't do this any more. When deleting an object in a thread the onChange event is called.