我有这种情况: 一个很快产生物品的流 在UI线程上做了大量工作的订阅者。
当遇到某种情况时,我想取消订阅,以免发生额外的工作。
我还想在重新订阅的情况下做一些额外的工作。
实施例: 网络事件产生对项目的更新,模型监听它并更新项目并使用更新的项目公开新的observable。 屏幕订阅模型的流并相应地更新GUI。 一个新的屏幕打开,所以我们不再需要在前一个屏幕上更新它的GUI了 - >取消订阅(当模型仍在更新时) 新屏幕关闭,使前一个屏幕再次可见,因此需要重新订阅,因为它没有听过一段时间需要刷新它的视图。
我有一些解决方案,但我觉得可能有更好的解决方案:
我可以使用过滤器来检查条件。并且只是过滤那些项目,但我更喜欢完全取消订阅,因为它会更有效率。
isScreenVisibleObs().subscribe(isVisible -> {
if (isVisible){
subscription = getItemsUpdateObs().subscribe(...)
} else {
if ( subscription != null) subscription.unsubscribe()
}});
我可以用来订阅和监听条件事件。然后根据该事件订阅/取消订阅每次都有一个全新的订阅 - 这是一个程序解决方案而不是功能解决方案。 我想过使用窗口操作符并将其展平,但我不确定这是一个简单的解决方案。
getItemsUpdateObs().compose(listenWhen(isScreenVisibleObs()).subscribe(...)
有什么想法吗?
我想这样做:
json.dumps (data)
哪里听,这里的问题是什么......
答案 0 :(得分:1)
保存Observable.subscribe()方法的返回类型。在上一个屏幕的onActivityResult中再次重新发起请求
Subscription subscription = Observable.subscribe(new Subscriber<Type>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String responseString) {
}
});
每当您提出下一个请求时,只需检查之前的呼叫状态(已完成/正在运行) 如下。如果没有完成取消上一个电话,并按如下方式提出新请求。
if(subscription!=null && !subscription.isUnsubscribed()){
//Cancel(unSubscribe) the request if running(not completed)
subscription.unsubscribe();
//START A NEW REQUEST HERE
}else{
//already completed so START A NEW REQUEST
}
答案 1 :(得分:1)
RxJava中有一个名为switchMap()
的非常有用的运算符。它将根据可观察的内容切换订阅。
首先根据您的屏幕是否处于活动状态来设置您的observable:
Observable<Boolean> isActive;
然后,根据可观察的内容进行切换:
isActive
.switchMap( active -> active ? getItemsUpdateObs() : Observable.never() )
.subscribe( ... );
这只会在屏幕处于活动状态时订阅项目更新。每个屏幕需要一个可观察的,但它们很便宜。这样,可观察链保持其自身状态,并为您处理订阅和重新订阅的正确管理和时间。
答案 2 :(得分:0)
我甚至不关心前一个下属是否完成。在您要为新请求创建新订户的下一个窗口中,只需取消订阅订阅,所有订阅者将自动取消订阅。
然后创建一个新订阅者并再次订阅该订阅。
/**
* You can in any moment unsubscribe all subscriber of a subscription and create a new one again.
* @throws InterruptedException
*/
@Test
public void subscribeAndUnsubscribe() throws InterruptedException {
Integer[] numbers = {0, 1, 2, 4, 5, 6};
Observable<Integer> observable = Observable.from(numbers);
Subscription subscription = observable.subscribeOn(Schedulers.newThread()).subscribe(createSubscriber());
Thread.sleep(2000);
subscription.unsubscribe();
subscription = observable.subscribeOn(Schedulers.newThread()).subscribe(createSubscriber());
Thread.sleep(10000);
System.out.println(subscription.isUnsubscribed());
}
private ActionSubscriber createSubscriber() {
return new ActionSubscriber(number -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("preparing to unsubscribe");
}
System.out.println("Subscriber number:" + number);
},
System.out::println,
() -> System.out.println("Subscriber End of pipeline"));
}