【问题标题】:How to unsubscribe from an Observable when using an Android library使用 Android 库时如何取消订阅 Observable
【发布时间】:2014-10-05 18:47:34
【问题描述】:

Why is my timer Observable never called? @Miguel Lavigne 说:

“请记住,如果您在 Fragment 或 Activity 中使用 Observable,则应始终确保取消订阅 Observable,以消除内存泄漏的可能性。”

只要我在 Activity、Fragment 或 View 中使用 Observable,我就很清楚它是如何工作的。但是如果我在没有上下文的地方使用它呢?

我的情况:我有一个包含对象模型的外部库。每个对象都有一个从 UI 调用的 .save() 函数。在 save 中,API 端点调用由 Observable 异步执行。

例子:

public Overlay save() {
        Observable.create(new Observable.OnSubscribe<Overlay>() {

        @Override public void call(Subscriber<? super Overlay> subscriber) {
            try {
                Overlay overlay= OverlayEndpoint.insertOverlay(this); // call the API endpoint here
                subscriber.onNext(overlay);
                subscriber.onCompleted();
            } catch (IOException e) {
                subscriber.onError(e);
            }
        }

    }).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<Overlay>() {

                @Override public void call(Overlay overlay) {
                    // process the saved result [omitted for brevity]
                }

            }, new Action1<Throwable>() {

                @Override public void call(Throwable throwable) {
                    // put the overlay into a local upload queue in case the endpoint is unreachable [omitted]
                }

            });

    return this; // return the call immediately
}

Observable 是在 save 中一次性使用的,之后就过时了。如何确保它不会持续存在?

情况一:正常退订。处理完成后,有没有办法直接在 call() 中取消订阅?

情况 2:无论出于何种原因,Observable 都留在内存中。我可以使用 .timeout() 来确保 Observable 在经过足够的时间后被销毁吗?

【问题讨论】:

    标签: android rx-java


    【解决方案1】:

    情况一:正常退订。处理完成后,有没有办法直接在 call() 中取消订阅?

    在您的情况下,Observable 将在调用 Action1&lt;Overlay&gt;new Action1&lt;Throwable&gt; 之前在内存中。但是在其中一个被调用之后,GC应该能够清理Observable

    情况 2:无论出于何种原因,Observable 都留在内存中。我可以使用 .timeout() 来确保 Observable 在经过足够的时间后被销毁吗?

    在您的情况下,Schedulers.newThread() 将创建一个新的Thread 来运行Observable.OnSubscribe&lt;Overlay&gt;.call。所以如果这个方法还没有返回,比如OverlayEndpoint.insertOverlay会运行10分钟左右,Observable就不能被GC清理掉,因为这个线程还在使用它。除非有办法取消OverlayEndpoint.insertOverlay,否则我们无能为力。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-20
      • 1970-01-01
      • 2020-08-29
      • 1970-01-01
      • 1970-01-01
      • 2016-12-20
      • 1970-01-01
      相关资源
      最近更新 更多