2014-10-05 60 views
3

Why is my timer Observable never called? @Miguel儿说:记住如何从可观察使用的是Android库时取消

“记住,如果你使用的观测量从一个片段或一个活动中,你应该始终确保你取消订阅您的Observables以消除内存泄漏的可能性。“

只要我在活动,片段或视图中使用Observable,我就很清楚它是如何工作的。但是如果我在没有语境的情况下使用它呢?

我的情况:我有一个包含对象模型的外部库。每个对象都有一个.save()函数,它可以从UI中调用。在保存中,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 
} 

可观察为一次性使用的内保存并随后变得过时。我怎样才能确保它不会持续?

情况1:正常退订。一旦处理完成,是否有方法可以在调用()内取消订阅?情境2:无论出于何种原因,Observable都留在记忆中。我可以使用.timeout()来确保Observable在足够的时间过去之后被销毁吗?

回答

2

情况1:正常取消订阅。一旦处理完成,是否有方法可以在调用()内取消订阅?

在你的情况,Observable会在内存Action1<Overlay>new Action1<Throwable>被调用之前。但是在调用其中一个之后,GC应该能够清除Observable

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

在你的情况,Schedulers.newThread()将创建一个新的Thread运行Observable.OnSubscribe<Overlay>.call。因此,如果此方法尚未返回,例如OverlayEndpoint.insertOverlay将运行约10分钟,则Observable无法用GC进行清理,因为此线程仍在使用它。除非有办法取消OverlayEndpoint.insertOverlay,否则我们无能为力。