How to clear the fire of RxJava and forget the subscription?

I have a fire and forget operations that do not take a very long time, but long enough so that I can run them in the background. There, the lifetime is mainly while the connection to the server exists or 10 seconds have passed. I do not know how to store them, so that I can clean them effectively, while maintaining the correct life cycle.

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???? 

I can have a CompositeSubscription on my connection that holds them in my hands, but how can I clear them after the operation is completed? Should I even ask to clear the composite subscription when the subscription is canceled? I'm relatively new to Rx, so I'm not sure I'm just trying to do what Rx was not meant to do.

+6
source share
3 answers

Hint: Fire and Forget

You do not forget that you support the subscription. Just call a subscription and go.

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

Edit : garbage collection.

If you are not doing something very strange (for example, using WeakReference), your doSomething prevent the entire chain from being collected.

Think of RxJava as a bow, every time you transform an observable (map, doOnNext, etc.), a new Observable is created that wraps the old observable like a bow.

For each conversion, a new Subscriber is created that passes callbacks (onNext, onCompleted, onError) to the next Subscriber in the chain.

The main reason for Subscription is that you can call unsubscribe . There are two reasons why you can unsubscribe.

  • You have a hot observable. Basically, this observable will radiate values ​​forever. An example would be an observed value that emits a time every 30 seconds. You can call unsubscribe when you are no longer interested in the meaning of time.

  • You want to cancel a long operation. Suppose you are loading a web page to display to the user, if the user clicks back, you want to cancel the download (you no longer care about the results).

Example Source code for a card operation

The map simply calls lift with the OperatorMap argument. Lift creates a new Observable based on Operator , so far it can be ignored.

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

OperatorMap creates a new Subscriber that basically just transfers the calls to all the Subscriber that it defines. It can be a Subscriber that you pass to a subscribe or a Subscriber created by another map transformation, it doesn't really matter.

 public final class OperatorMap<T, R> implements Operator<R, T> { private final Func1<? super T, ? extends R> transformer; public OperatorMap(Func1<? super T, ? extends R> transformer) { this.transformer = transformer; } @Override public Subscriber<? super T> call(final Subscriber<? super R> o) { return new Subscriber<T>(o) { @Override public void onCompleted() { o.onCompleted(); } @Override public void onError(Throwable e) { o.onError(e); } @Override public void onNext(T t) { try { o.onNext(transformer.call(t)); } catch (Throwable e) { Exceptions.throwOrReport(e, this, t); } } }; } } 
+4
source

Forget about getting a subscription if you don't want to know if it is still subscribing. By design, the Observable will disable the onComplete observer. Then, since the instance is no longer in use, the GC will delete it at some point.

just reorganize your code:

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

Here you can see examples of how the subscription works.

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

+1
source

Your CompositeSubscription should be stored in any parent object to your liking. This will bind the CompositeSubscription parent life cycle to the CompositeSubscription itself: When the parent becomes inaccessible, the CompositeSubscription with the parent will be garbage collected.

Additionally, if the parent CompositeSubscription element has lifecycle methods such as onStop() , you can manually unsubscribe the CompositeSubscription . Similarly, if you have a lifecycle method available, such as onStart() or onResume() , you can subscribe (again) there.

This page can provide you more information about garbage collection.

0
source

All Articles