如何清理RxJava fire并忘记订阅?

时间:2016-06-09 16:05:37

标签: java android rx-java

我有火并且忘记了不需要很长时间的操作,但是我想要在后台反复运行它们。生命周期基本上是与服务器的连接存在或已经过了10秒。我不知道如何存储它们,这样我就可以有效地清理它们,同时保持正确的生命周期。

Subscription fireAndForget = service.doSomething()
                                    .timeout(10, TimeUnit.SECONDS)
                                    .subscribe( () -> {
                                        otherService.doAction()
                                    }, (e) -> { Log.e("error", e) });
// what do I do with fireAndForget???

// If I use a CompositeSubscription
subscriptions.add(fireAndForget) // how does it get removed????

我的连接上有一个CompositeSubscription可以保留它们,但是当操作完成后如何清除它们呢?在订阅取消订阅时,我是否应该打扰清除CompositeSubscription?我对Rx比较陌生,所以我不确定我是不是只是想做一些Rx不应该做的事情。

3 个答案:

答案 0 :(得分:8)

提示:火和忘记

如果您保持订阅,您不会忘记。只需致电订阅并继续前进。

service.doSomething()
    .timeout(10, TimeUnit.SECONDS)
    .subscribe( () -> {
        otherService.doAction()
    }

修改:垃圾收集。

除非你做一些非常奇怪的事情(比如使用WeakReference),否则doSomething中执行的代码将阻止整个链被垃圾收集。

将RxJava想象成一个洋葱,每次变换一个observable(map,doOnNext等)时,都会创建一个新的Observable,将旧的observable包装成洋葱。

对于每个转换,都会创建一个新的Subscriber,它将回调(onNext,onCompleted,onError)传递给链中的下一个Subscriber

Subscription的主要原因是您可以致电unsubscribe。您可能想要取消订阅有两个原因。

  1. 你有一个热门的观察者。基本上这个可观察者将永远发出价值。一个例子可以是一个可观察的,每30秒发出一次。当您不再对时间价值感兴趣时,可以致电unsubscribe

  2. 您想取消长时间的操作。假设您正在加载一个网页以显示给用户,如果用户按下,您想要取消加载(您不再关心结果)。

  3. 示例地图操作的源代码

    地图只需使用lift作为参数调用OperatorMap。 Lift会根据Observable创建一个新的Operator,暂时可以忽略它。

    public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
        return lift(new OperatorMap<T, R>(func));
    }
    

    OperatorMap创建了一个新的Subscriber,它主要只是将调用传递给它所提供的任何Subscriber。这可能是您传入Subscriber的{​​{1}}或另一个subscribe转化所创建的Subscriber,这并不重要。

    map

答案 1 :(得分:1)

忘记获取订阅,除非您想知道是否仍然订阅。按设计,Observable将取消订阅观察者onComplete。然后,由于实例不再使用,GC在某些时候会将其删除。

重构您的代码:

    service.doSomething().timeout(10, TimeUnit.SECONDS)
                                .subscribe( () -> {
                                    otherService.doAction()
                                }, (e) -> { Log.e("error", e) });

您可以在此处查看有关订阅如何工作的示例。

https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/creating/ObservableSubscription.java

答案 2 :(得分:0)

您的width应存储在您喜欢的任何父对象中。这会将CompositeSubscription父级的生命周期与CompositeSubscription本身联系起来: 当父对象变得无法访问时,带有父对象的CompositeSubscription将被垃圾收集。

此外,如果CompositeSubscription的父级有CompositeSubscription等生命周期方法,您可以手动取消订阅onStop()。同样,如果您有可用的生命周期方法,例如CompositeSubscriptiononStart(),则可以(再次)订阅。

This page可能会为您提供有关垃圾收集的更多信息。