sudshekhar
sudshekhar

Reputation: 1666

rxJava Observer.onNext not called second time

I am using rxJava to fetch data from the database and show it in a recyclerview. The relevant code is shown below

function updateUI(){
  ContactsLab contactsLab = ContactsLab.get(getActivity());
  Subscription sub = contactsLab.getContactList().subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .toList()
            .subscribe(onContactsReceived());
  mCompositeSubscription.add(sub);
}

ContactsLab is a singleton that returns an Observable of Contact objects. onContactsReceived function is shown below

private Observer<List<Contact>> onContactsReceived(){
    return new Observer<List<Contact>>() {
        @Override
        public void onCompleted() {}

        @Override
        public void onError(Throwable e) {}

        @Override
        public void onNext(List<Contact> contacts) {
            if(mContactsAdapter == null) {
                mContactsAdapter = new ContactsAdapter(contacts);
                mRecyclerView.setAdapter(mContactsAdapter);
            } else{
                mContactsAdapter.setContactList(contacts);
                mContactsAdapter.notifyDataSetChanged();
            }
        }
    };
}

The updateUI function is called in my fragment onResume but the view is updated only the first time. If I come back to this fragment from any other fragment (having added more items to db), onResume is called, updateUI runs and onContactsReceived also runs but returns immediately without calling onNext or onComplete.

I think this has something to do with the way rxJava handles observables but no idea how to fix it (read about defer but couldn't understand much). Can somebody please help?

Edit:

The getContactList function look like this :

public rx.Observable<Contact> getContactList() {
    List<Contact> contacts = new ArrayList<>();
    ContactCursorWrapper cursorWrapper = queryContacts(null, null);
    try{
        cursorWrapper.moveToFirst();
        while (!cursorWrapper.isAfterLast()){
            contacts.add(cursorWrapper.getContact());
            cursorWrapper.moveToNext();
        }
    } finally {
        cursorWrapper.close();
    }
    return rx.Observable.from(contacts);
}

Basically it queries the database and maps the returned Cursor into my Contact class(which is a POJO). I added the rx.Observable.from to get an observable that was later collated using toList and updated into the adapter. I used this approach avoid having to call notifyDataSetChanged after getting each item (and call it only once after getting all that).

What's the right approach to minimize the number of notifyDataSetChanged calls and also, refresh each time onResume is called?

Upvotes: 1

Views: 1570

Answers (1)

JohnWowUs
JohnWowUs

Reputation: 3083

Your observable contactsLab.getContactList().toList() has terminated.toList() collects all emissions from a source observable to a list and emits the entire list once the source Observable terminates (see the documentation). You aren't going to observe any more emissions from it.

Upvotes: 2

Related Questions