I have a model Member extends RealmObject. In my activity, I set onAddChangeListener on it as follows:
private RealmChangeListener<RealmResults<Member>> memberTracker = this::setupProfileUI;
private Member member;
private void setupProfileUI(RealmResults<MemberDetails> results) {
member = results.first(null);
updateProfileUI();
}
and in onCreate(), I do
RealmResults<Member> memberResults = realm.where(Member.class).findAll();
memberResults.addChangeListener(memberTracker);
member = memberResults.first(null);
I update member object on a background thread based on selection of a spinner
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
Request.updateMember(new Request.Callback<Member>() {
@Override
public void onResponse(Response<Member> response) {
Log.d(TAG, "updateMember: " + member.getLocation().getCity());
Log.d(TAG, "updateMember: " + response.body().getLocation().getCity());
}
@Override
public void onFailure(Throwable t) {
Log.e(TAG, "onFailure: Member Update Failed");
}
});
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
The second Log statement in onResponse callback prints Member's city from response from an API while first prints city value from current value of member. The later value remains unchanged and Activity receives no update Notification.
Member is updated in Request.updateMember() through a call to a helper function as follows
private static void updateMemberDetails(Response<Member> response) {
if (response.isSuccessful()) {
try(Realm realmInstance = Realm.getDefaultInstance()) {
Member member = response.body();
if (member != null) {
realmInstance.executeTransaction(realm -> realm.insertOrUpdate(member));
}
}
}
}
I checked the .realm file manually on successful async call that member in .realm file was indeed updated but the member object in Activity doesn't gets updated nor there is any update notification.
RealmResults<Member> memberResults = realm.where(Member.class).findAll();
As per documentation of RealmResults.addChangeListener :
Registering a change listener will not prevent the underlying RealmResults from being garbage collected. If the RealmResults is garbage collected, the change listener will stop being triggered. To avoid this, keep a strong reference for as long as appropriate e.g. in a class variable.
public class MyActivity extends AppCompatActivity {
private RealmResults<Person> results; // Strong reference to keep listeners alive
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
results = realm.where(Person.class).findAllAsync();
results.addChangeListener(new RealmChangeListener<RealmResults<Person>>() {
@Override
public void onChange(RealmResults<Person> persons) {
// React to change
}
});
}
}
So you should do exactly that.