jpact
jpact

Reputation: 1072

Realm's RealmChangeListener as anonymous class does not get called every time

I am trying to solve an issue about Realm's RealmChangeListener added as anonymous class. The problem is, that sometimes it gets called, but sometimes not. However, if class implements RealmChangeListener and to query is added as this, everything works fine.

In following example, when I open the app, 4 requests are made to local repository to load data from database at the same time. So getUsers method is called 4 times, each time with different User.Type value. However, most of the time (80%) RealmChangeListener is called just once.

This is not working

public class Repo {

    Reaml mRealm;

    public Repo(@Inject Realm realm){
        this.mReal = realm;
    }

    public void getUsers(User.Type type, Callbacks callbacks){
        mRealm.where(User.class)
            .equalTo("type", type.name())
            .findAllSortedAsync("firstName", Sort.ASCENDING)
            .addChangeListener(new new RealmChangeListener<RealmResults<User>>() {
                @Override
                public void onChange(RealmResults<User> element) {
                    if (element.isLoaded()) {
                        Log.d("%s users are loaded", type.name());
                        callbacks.onUsersLoaded(element);
                        element.removeChangeListener(this);
                    }
                }
            }));
        }
    }
}

However, if Repo class implements RealmChangeListener and I pass it to RealmResults as this reference, it get called properly, 4 times.

This is working!

public class Repo implements RealmChangeListener<RealmResults<User>>{

    Reaml mRealm;

    public Repo(@Inject Realm realm){
        this.mReal = realm;
    }

    public void getUsers(User.Type type, Callbacks callbacks){
        mRealm.where(User.class)
            .equalTo("type", type.name())
            .findAllSortedAsync("firstName", Sort.ASCENDING)
            .addChangeListener(this);
    }

    @Override
    public void onChange(RealmResults<User> element) {
        if (element.isLoaded()) {
            Log.d("Users are loaded from THIS");
            callbacks.onUsersLoaded(element);
            element.removeChangeListener(this);
        }
    }
}

Do you have any suggestions where could be a problem and how could I solve that ? I would like to use anonymous class instead of reference to this. I was trying to search for solution on SO, Realm's documentation, GitHub, but no success.

Thanks in advance

Upvotes: 0

Views: 297

Answers (1)

jpact
jpact

Reputation: 1072

Well,

answer is pretty easy and as @beeender pointed out, results got GCed. I didn't realize that even if I had a local variable final RealmResults<User> result to which I was assigning result of . findAllSortedAsync, it got GCed almost immediately after method body was executed.

So, the solution is to change RealmResults<User> result from local variable to instance variable.

Upvotes: 3

Related Questions