How to unsubscribe from Observable when using Android library

Q Why has my Observable timer never rang? @ Miguel Lavigne says:

"Keep in mind that if you are using Observables from a Fragment or Activity, you should always be sure to unsubscribe your observers to eliminate the possibility of a memory leak."

It is clear to me how this works as long as I use Observable in Activity, Fragment or View. But what if I use it where there is no context?

My situation: I have an external library that contains an object model. Every object has a .save () function that is called from the user interface. In save, the call to the API endpoint is done asynchronously.

Example:

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 is one-time use during save and becomes obsolete thereafter. How can I make sure it is not being saved?

Situation 1: Normal cancellation of a subscription. Is there a way to unsubscribe directly from the call () once processing is complete?

Situation 2: For some reason, the Observable remains in memory. Can I use .timeout () to ensure that the Observable is destroyed after enough time has passed?

+3


source to share


1 answer


Situation 1: Normal cancellation of a subscription. Is there a way to unsubscribe directly from the call () once processing is complete?

In your case Observable

will be in memory before calling Action1<Overlay>

or new Action1<Throwable>

. But after calling one of them the GC should clean up Observable

.



Situation 2: For some reason, the Observable remains in memory. Can I use .timeout () to ensure that the Observable is destroyed after enough time has passed?

In your case Schedulers.newThread()

will create a new one Thread

to run Observable.OnSubscribe<Overlay>.call

. So if this method has not returned yet, for example OverlayEndpoint.insertOverlay

will run for about 10 minutes, the Observable

GC cannot be flushed because this thread is still using it. There is nothing we can do if there is a cancellation approach OverlayEndpoint.insertOverlay

.

+2


source







All Articles