Rx java 使用RxJava更新和保留现有数据

Rx java 使用RxJava更新和保留现有数据,rx-java,reactive-programming,rx-java2,Rx Java,Reactive Programming,Rx Java2,我正在考虑将我(Android)应用程序中的一些逻辑转换为使用RxJava,但是我很难想出一种方法来实现一些更高级的逻辑 用例如下:我想向用户显示一种提要。提要由来自不同来源的项目组成,例如消息、文章等。由于API限制,应用程序本身必须收集各个来源,并将其显示在一个列表中 例如,假设提要中的我的项目如下所示: 类饲料项目{ Type feedItem;//项目的类型,例如文章、消息等。 ... } 目前,提要构建在一个单独的线程上,当提要被更新时,会使用侦听器通知UI。为了让您了解它是如何完成

我正在考虑将我(Android)应用程序中的一些逻辑转换为使用RxJava,但是我很难想出一种方法来实现一些更高级的逻辑

用例如下:我想向用户显示一种提要。提要由来自不同来源的项目组成,例如消息、文章等。由于API限制,应用程序本身必须收集各个来源,并将其显示在一个列表中

例如,假设提要中的我的项目如下所示:

类饲料项目{
Type feedItem;//项目的类型,例如文章、消息等。
...
}
目前,提要构建在一个单独的线程上,当提要被更新时,会使用侦听器通知UI。为了让您了解它是如何完成的,下面是一些(伪)Java代码(为了清晰起见,省略了线程和其他管理代码)

类FeedProducer{
List currentData=new ArrayList();
公共数据(){
对于(FeedSource源:getFeedSources()){
类型sourceType=source.getType();
//删除现有项目
currentData.removeIf(item->item.feedItem.equals(sourceType));
List newItems=source.produceItems();
//添加新项目
currentData.addAll(新项目);
//通知用户界面发生了变化
notifyDataChanged(当前数据);
}
//通知UI我们已完成加载
notifyLoadingComplete();
}
}
每次用户希望刷新数据时,都会调用此方法
refreshData()
。这样,可以只更新一些源,而其他源保持不变(例如,通过更改
getFeedSources()
的返回值)

这些资源也单独用于应用程序的其他部分;我已经把它们转换成了观测值。这使事情变得容易得多,例如,如果数据库发生了更改,那么这些更改就可以通过可观察对象简单地推送到UI


因此,我的问题是,我如何(优雅地)将这些可观察的源合并成一个可观察的源,但之前的结果存在“全局”状态。我已经研究了各种合并运算符,但没有找到我需要的。如果我忽略了一些显而易见的事情,我深表歉意,因为我对RxJava是相当陌生的。

如果您有3个返回
[0,1]
[10,11]
[20,21]
的单独任务,您希望将它们合并到一个列表中。在这种情况下,可以使用
zip
操作

public class TestRx {
    public static void main(String[] args) {
        // some individual observables.
        Observable<List<Integer>> observable1 = Observable.just(Arrays.asList(0, 1));
        Observable<List<Integer>> observable2 = Observable.just(Arrays.asList(10, 11));
        Observable<List<Integer>> observable3 = Observable.just(Arrays.asList(20, 21));

        Observable.zip(observable1, observable2, observable3,
                new Func3<List<Integer>, List<Integer>, List<Integer>, List<Integer>>() {
                    @Override
                    public List<Integer> call(List<Integer> list1, List<Integer> list2, List<Integer> list3) {
                        // TODO: Remove existing items

                        // merge all lists
                        List<Integer> mergedList = new ArrayList<>();
                        mergedList.addAll(list1);
                        mergedList.addAll(list2);
                        mergedList.addAll(list3);
                        return mergedList;
                    }
                })
                .subscribe(new Observer<List<Integer>>() {
                    @Override
                    public void onNext(List<Integer> mergedList) {
                        System.out.println(mergedList);
                        // TODO: notifyDataChanged(mergedList)
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        System.out.println(throwable.toString());
                        // TODO: handle exceptions
                    }

                    @Override
                    public void onCompleted() {
                        // TODO: notifyLoadingComplete()
                    }
                });
    }
}
公共类TestRx{
公共静态void main(字符串[]args){
//一些单独的观测值。
Observable Observable 1=Observable.just(Arrays.asList(0,1));
Observable Observable 2=Observable.just(Arrays.asList(10,11));
Observable Observable 3=Observable.just(Arrays.asList(20,21));
可观察的。zip(可观察的1,可观察的2,可观察的3,
新功能3(){
@凌驾
公共列表调用(列表1、列表2、列表3){
//TODO:删除现有项
//合并所有列表
List mergedList=new ArrayList();
mergedList.addAll(列表1);
mergedList.addAll(列表2);
mergedList.addAll(列表3);
返回合并列表;
}
})
.订阅(新观察员){
@凌驾
public void onNext(列表合并列表){
System.out.println(合并列表);
//TODO:notifyDataChanged(合并列表)
}
@凌驾
公共作废登记员(可丢弃){
System.out.println(throwable.toString());
//TODO:处理异常
}
@凌驾
未完成的公共无效(){
//TODO:notifyLoadingComplete()
}
});
}
}

因此,它会这样打印
[0,1,10,11,20,21]

简单的选项是,调用方存储最后一个列表,并在您请求新数据时将其作为参数提供:

公共类反应性多资源{
//区域类
公共枚举源类型{
第u类文章,
键入_消息,
类型视频
}
公共静态类提要{
私有SourceType SourceType;
私有字符串内容;
提要(SourceType SourceType,字符串内容){
this.sourceType=sourceType;
this.content=内容;
}
SourceType getSourceType(){
返回源类型;
}
}
//端区
公共静态void main(字符串[]args)引发InterruptedException{
最终列表[]当前列表=新列表[]{new ArrayList()};
//模拟刷新
刷新内容(当前列表[0])
.订阅(订阅源->{
currentList[0]=提要;
对于(int i=0;i{
currentList[0]=提要;
对于(int i=0;iarticle 19
article 15
article 18
article 18
message 3
message 2
message 9
message 1
video 19
video 17
video 18
video 11

article 0
article 4
article 18
article 15
message 11
message 16
message 16
message 4
video 1
video 7
video 20
video 2