观察数据库中的更改以更新列表

时间:2017-03-03 13:04:07

标签: android rx-java

我有FriendRepository

public class FriendRepository {

    //return all friends from database
    public Observable<Friend> getAll() {
        return Observable.defer(new Func0<Observable<Friend>>() {
            @Override
            public Observable<Friend> call() {
                //Query from database and return all friends
            }
        });
    }

    public Observable<Friend> add(Friend friend) {
        //Store a new Friend to database
    }

}

在我的ListActivity中,我做了类似的事情:

friendRepository.getAll().subscribe(addFriendToList());

但是,从Android Service开始,可能会使用Friend方法添加新的FriendRepository.add()。我希望ListActivity知道这个变化,所以我需要以某种方式发布它。我知道PublishSubject存在,但在这种情况下我不知道如何使用它。

FriendRepository.add()方法中,我会做类似的事情:

    public Observable<Friend> add(Friend friend) {
        return storeFriend().doOnCompleted(new Action0() {
            @Override
            public void call() {
                publisSubject.onNext(friend);           
            }
        });
    }

但我不知道在FriendRepository.getAll()方法中要返回什么。

2 个答案:

答案 0 :(得分:2)

我认为这应该有效:

public Observable<Friend> getAll() {
    return Observable.defer(new Func0<Observable<Friend>>() {
        @Override
        public Observable<Friend> call() {
            //Query from database and return all friends
        }
    })
    .concatWith(publishSubject.asObservable());
}

通过这种方式,您可以在defer订阅时获取当前状态,并通过Subject获取所有未来更新。

答案 1 :(得分:2)

您需要将该发布主题存储为字段成员,并将其与您的流合并以进行查询,如下所示:

public class FriendRepository {

    PublishSubject<Friend> mFriendsSubject = PublishSubject.create();

    //return all friends from database
    public Observable<Friend> getAll() {
        return Observable.defer(new Func0<Observable<Friend>>() {
            @Override
            public Observable<Friend> call() {
                //Query from database and return all friends
            }
        })
        .mergeWith(mPublishSubject);
    }

    public Observable<Friend> add(Friend friend) {
        return storeFriend().doOnCompleted(new Action0() {
            @Override
            public void call() {
                mFriendsSubject.onNext(friend);           
            }
        });
    }

}

但以这种方式通知会违反 单一事实来源 原则,因为您只会通知您的存储库中发生的更改。为了解决这个问题,我建议使用数据包装器,为您处理通知流(Requery,Realm,SQLBrite等..)