Make Single Observable发出不止一次

时间:2016-12-17 18:26:49

标签: android rx-java

当我收到推送通知时,我会通过以下方式将通知有效负载添加到我的数据库:

personObject.insertObjectIntoDb(searchResult, value, oneOnOneChannel).observeOn(Schedulers.computation()).subscribe(insertSinglePersonSubscriber);

我在我的活动的Subscriber中实例化了onCreate()

insertSub = new Subscriber<Long>() {
    @Override
    public void onCompleted() {
        Log.d(TAG, "onCompleted: insertSub complete");
    }

    @Override
    public void onError(Throwable e) {
        Log.d(TAG, "onError: insertSub error");
    }

    @Override
    public void onNext(Long aLong) {
        Log.d(TAG, "onNext: insertSub next");
    }
};

personObject.insertObjectIntoDb()的第一次调用中,onComplete()的{​​{1}}被调用,就像预期一样。

这意味着现在insertSub已经结束,订阅者将取消订阅。

但是,我不想停止订阅,并希望每次有新的推送通知时都会调用insertSub回调。

我一直在为一个可观察的和多个订阅者阅读subscription,但这不是我想要的。我读到了share(),但是观察到它永远不会停止发射(oops)。将replay()更改为Subscriber也没有帮助,并且在更全面的阅读中,我发现订阅者继承自Observer并且适用相同的规则(除了订阅者之外我们需要取消订阅。

我不确定观察者观察者是否停止发射(发射一次后)。每当有新通知时,如何让observable多次发出?

此外,重新建立订阅的最佳方法是什么?

3 个答案:

答案 0 :(得分:4)

首先,根据您的描述,似乎您没有完全弄清楚一些基本概念。

观察员 请勿 发出 ,而是 接收 < / strong>排放。

单身 不能多次发出。它们被设计为仅发射一个事件并完成。如果您不想要这种行为,则需要使用其他一些Observable类型。

但单身在这里不是问题。要编写一个行为如此的流,您需要考虑上面的一个级别。如果您设计一个从推送通知接收信号的流,您可以通过订阅您的Single并将其发送回到主要通知流来对每个流做出反应。这样,您就可以将所有排放信息汇集到一个 Observer 中,就像您所描述的那样。使用flatMap运算符可以轻松实现此目的。

notificationStream
    .flatMap(notificationPayload -> 
         personObject
             .insertObjectIntoDb(/* Extract arguments from payload */)
             .subscribeOn(Schedulers.computation())
    )
    .subscribe(insertSinglePersonSubscriber)

notificationStream可以通过使用专为其设计的库(即https://android-arsenal.com/details/1/3546),自己编写或使用 主题 来创建。最简单的方法绝对是第三种,虽然不是最干净的。您只需创建一个主题并在您订阅的位置调用其onNext方法,即可立即插入对象。

在编写流以插入值时,我将observeOn运算符更改为subscribeOn,因为我猜您并不完全了解每个运算符的作用。

observeOn运算符 切换 调度程序,其中是从流的该点处理的排放。

另一方面,subscribeOn运算符指示observable在特定调度程序上生成项。我希望我可以假设你在单身本身产生排放时做了“繁重的工作” - 那就是插入本身 - 你需要 订阅 计算调度程序,不在其上观察。如果我错了,你需要在观察者中进行计算工作,那么在observeOn之后在通知流上添加flatMap运算符。

RxJava很棒,继续学习。但理论知识很重要: - )

答案 1 :(得分:0)

使用relay怎么样?中继是subject,但不能调用onComplete或onError

https://github.com/JakeWharton/RxRelay

在这里你可以看到一个实际的例子

https://github.com/politrons/reactive/blob/master/src/test/java/rx/relay/Relay.java

答案 2 :(得分:0)

在我找到解决整体问题的方法时回答这个问题。

基本上,我想在他的回答中提到notificationStream作为@koperko。但他建议创建一个主题(PublishSubject,如果我没有错的话)。

但这只能解决我问题的一半。我想要做的是获取一条通知Stream,将通知添加到我的数据库中,在插入之后,通过获取最后插入的通知来更新UI。

personObject.insertObjectIntoDb(person)
    .observeOn(Schedulers.computation())
    .switchMap(new Func1<Long, Observable<PersonObject>>() {
        @Override
        public Observable<PersonObject> call(Long aLong) {
            Log.d(TAG, "call: inserted into DB with ID " + aLong);
            Log.d(TAG, "call: Now fetching this item from the DB");
            return personObject.getPersonById(aLong).observeOn(Schedulers.computation());
        }
    }).subscribe(getSinglePersonFromDBSubscriber);

这不仅使我不必创建Subject,而且还使我免于担心试图使Single's多次发出,而@koperko提到的不正确。我正在寻找switchMap()