2014-10-05 3 views
3

В Why is my timer Observable never called? @Miguel Лавин говорит:Как отказаться от подписки на наблюдаемом при использовании Android библиотеки

«Имейте в виду, что если вы используете Наблюдаемые внутри фрагмента или деятельности, вы всегда должны убедиться, что вы отписаться от своих наблюдателей, чтобы исключить вероятность утечки памяти ».

Мне ясно, как это работает, пока я пользуюсь наблюдаемым в действии, фрагменте или представлении. Но что, если я использую его там, где нет контекста?

Мое положение: У меня есть внешняя библиотека, которая содержит объектную модель. Каждый объект имеет функцию .save(), которая вызывается из пользовательского интерфейса. При сохранении вызов конечной точки API выполняется асинхронным наблюдением.

Пример:

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: По какой-либо причине Наблюдаемый остается в памяти. Могу ли я использовать .timeout(), чтобы гарантировать, что Observable будет уничтожен после того, как прошло достаточно времени?

ответ

2

Ситуация 1: Нормальная отписаться. Есть ли способ отказаться от подписки прямо из вызова(), как только обработка завершена?

В вашем случае Observable будет в памяти до Action1<Overlay> или new Action1<Throwable> называется. Но после того, как один из них называется, GC должен уметь очищать Observable.

Ситуация 2: По какой-либо причине Наблюдаемый остается в памяти. Могу ли я использовать .timeout(), чтобы гарантировать, что Observable будет уничтожен после того, как прошло достаточно времени?

В вашем случае, Schedulers.newThread() создаст новый Thread запустить Observable.OnSubscribe<Overlay>.call. Поэтому, если этот метод еще не вернулся, например, OverlayEndpoint.insertOverlay будет работать около 10 минут, Observable не может быть очищен GC, потому что этот поток все еще использует его. Мы ничего не можем сделать, если есть подход к отмене OverlayEndpoint.insertOverlay.

Смежные вопросы