我使用rxJava从数据库中获取数据并在recyclerview中显示它。相关代码如下
function updateUI(){
ContactsLab contactsLab = ContactsLab.get(getActivity());
Subscription sub = contactsLab.getContactList().subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.toList()
.subscribe(onContactsReceived());
mCompositeSubscription.add(sub);
}
ContactsLab
是一个返回Contact对象的Observable的单例。onContactsReceived
函数如下图
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();
}
}
};
}
updateUI
函数在我的片段onResume
中被调用,但视图仅在第一次更新。如果我从任何其他片段(添加了更多的项目到db)回到这个片段,onResume
被调用,updateUI
运行,onContactsReceived
也运行,但立即返回,而不调用onNext
或onComplete
。
我认为这与rxJava处理可观察对象的方式有关,但不知道如何修复它(阅读defer
,但不能理解很多)。有人能帮帮我吗?
getContactList
函数是这样的:
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);
}
基本上它查询数据库并将返回的Cursor
映射到我的Contact类(这是一个POJO)。我添加了rx.Observable.from
来获得后来使用toList
整理并更新到适配器的可观察对象。我使用这种方法是为了避免在获得每个项目后调用notifyDataSetChanged
(并且在获得所有项目后只调用一次)。
减少notifyDataSetChanged
调用的次数,并且每次调用onResume
时刷新的正确方法是什么?
你的观察对象contactsLab.getContactList().toList()
已经终止。toList()
将源可观察对象的所有排放物收集到一个列表中,并在源可观察对象终止时排放整个列表(参见文档)。你不会再观察到它的任何排放物。