Android RX Java 2 disposable - java

When I used RXJava 1 I always kept track of my subscriptions to execute the unsubscribe in the activity onDestroy. Example: https://medium.com/#scanarch/how-to-leak-memory-with-subscriptions-in-rxjava-ae0ef01ad361
Recently I moved to RXJava 2 and then I looked online for suggestions of how to handle the new disposables.
But I can't find anything, every example that I see just ignore then.
Did RXJava 2 changed it and now I don't need anymore to execute the dispose method from the disposable or I should implement in the same way I was implementing in the RXJava 1 days?

If you get a Disposable with your subscription, you can as well use CompositeDisposable.
If you use some of the subscription methods not returning a Disposable, you could as well just use the takeUntil or takeWhile methods to dispose the subscription.

Related

RxJava2. Flowable to behave same way as Observable does?

It seems like mental overhead to use both Observable and Flowable in the same project for RXJava 2.
Say to distinguish in the interfaces that this method return Observable so there is not back-pressure this one does so it is with back-pressure support.
But in the end of the day we can just use Flowable to make things simpler?
Then:
Can I make Flowable to be faster to turn off pressure to behave same way as Observable does?
My answer to myself: use Flowable everywhere. For all API that exposed themselves through the Net.
My use case: I use RX Java to defining RX API to the Web and itneracting with other microservices by Net.
From my understanding, the projectreactor https://projectreactor.io/ (another rx iml) project there is even no question whether to go with backpressure or not. It is there for all Flux
Going back to RxJava2. It seems to me that in the RX Java it was decided to keep Observable for the backward compatibility purposes primary. (there is no good explanation why not)
And when it comes to HTTP I found that I need it even for smaller sets. Usually. Event if I return less than 1000 items to the client it does not mean that it can handle it at once (it can be busy doing other stuff), so I would go with backpressure.
So I do not won't to overcomplicate things / api / code, will go with Flowable everywhere until I see any of Observable.

What is the purpose of using a PublishSubject to trigger a disconnect rather than just unsubscribing from a Subscription in RxAndroid?

I'm working on a bluetooth project that uses RxAndroidBle for bluetooth communication. I came across two different ways that the subscriptions are cleaned up. I was wondering if anyone could explain the differences and benefits of each if there are any. The two examples are as follows.
First: using a PublishSubject to trigger a disconnect with the bluetooth device
Code Sample: https://github.com/Polidea/RxAndroidBle/blob/master/sample/src/main/java/com/polidea/rxandroidble/sample/example4_characteristic/CharacteristicOperationExampleActivity.java
Second: disconnecting with the bluetooth device by unsubscribing from the Subscription
Code Sample:
https://github.com/Polidea/RxAndroidBle/blob/master/sample/src/main/java/com/polidea/rxandroidble/sample/example2_connection/ConnectionExampleActivity.java
My main focus is on the triggerDisconnect() methods in each of the examples. In what ways is the PublishSubject way different from just keeping a reference to the Subscription and then unsubscribing?
I do apologize for how open ended this question is but I'm not sure how better to explain it.
No, PublishSubject disconnectTriggerSubject help construct connectionObservable using this prepareConnectionObservable() method earlier. Then act as a proxy to pass null to onNext() method of the observable.
Then inside onNext() of this subscription:
.subscribe(
characteristic -> {
updateUI(characteristic);
Log.i(getClass().getSimpleName(), "Hey, connection has been established!");
},
this::onConnectionFailure,
this::onConnectionFinished
);
the updateUI(characteristic) method is get called with null value.
I think I figured it out. The .takeUntil(disconnectTriggerSubject) is the key to understanding the disconnectTriggerSubject. takeUntil() means that items emitted from the connection observable (after subscribing of course) will be emitted until an item is emitted from disconnectTriggerSubject. Since disconnectTriggerSubject is a PublishSubject it is both an observer and observable. Due to it being an observable it can emit items through the onNext() method. So, calling disconnectTriggerSubject.onNext(null) causes takeUntil(disconnectTriggerSubject) to execute, which prevents any new items from the connectionObservable to be emitted. This is essentially the same as unsubscribe since it "Stops the receipt of notifications on the Subscriber that was registered when this Subscription was received." http://reactivex.io/RxJava/javadoc/rx/Subscription.html

How to add a common observer in rxjava

I am pretty new to rxjava and just started learning it and converting our android project to rx.
So I wrote observables and chained them using flatmaps to call apis and return an observable. Now in the main activity I subscribe to them and add my UI code to onNext, onSubscribe, onComplete and onError as applicable.
But I have mutiple apis for which I have created an observable for each api, but I want to have a wrapper over the observer with which I subscribe to them. It is mainly to execute a piece of code like logging onNext/onError calls and showing a progress status on onSubscribe and dismissing it on onComplete/onError etc.
How do I do this other than adding it each time or having a baseobserver and adding super.method each time (one may forget super.method hence this handling should be removed from activity code I guess)
The idea is to implement a BaseActivity where all other activities extends from it. In this activity, you declare your generic Observer and when extending from this class, you get that Observer and you can make your own modifications depending on your needs. Take a look at this code

What does share operator do in RxJava? When should I use it?

I know that share() is a replacement of publish().refCount().
Then from the RxJava wiki:
Observable.publish( ) — represents an Observable as a Connectable Observable
ConnectableObservable.refCount( ) — makes a Connectable Observable behave like an ordinary Observable
This make me confused. If after publish().refCount(), it just behave like an ordinary Observable, why should I use it, how does this api make sense?
You're right - Observable.share is just a shortcut for publish().refCount(). I think that description you have quoted above is not entirely clear as ConnectedObservable.refCount does a little bit more :)
If you transform your Observable to ConnectableObservable - it will not emit items (even if something is subscribed) unless explicitly called ConnectableObservable.connect - it basically defers execution of subscribe method and prevents from executing it multiple times for every subscriber. This technique is often used to make sure that all subscribers are subscribed before observable starts emitting items (in other words - after everyone has subscribed - connect() method is called).
If you have more than one subscriber (what often happens), you have to handle their subscriptions and unsubscriptions and this is where things are getting tricky. This is why refCount() was introduced. This operator returns new Observable, keeps track of how many subscribers are subscribed to it and stays connected as long as there is at least one subscription. It will also automatically connect when the first subscriber appears.
PS. I'm learning how to use RxJava, if I am wrong - please point it out!

How does task cancellation work in RxJava?

I'm unclear on how to implement task cancellation in RXJava.
I'm interested in porting an existing API built using Guava's ListenableFuture. My use case is as follows:
I have an single operation that's composed of a sequence of futures joined by Futures.transform()
Multiple subscribers observe the operation's final future.
Each observer can cancel the final future, and all observers witness the cancellation event.
Cancellation of the final future results in the cancellation of its dependencies, e.g. in sequence 1->2->3, cancellation of 3 is propagated to 2, and so on.
There's very little info in the RxJava wiki about this; the only references I can find to cancellation mention Subscription as an equivalent to .NET's Disposable, but as far as I can see, Subscription only offers the ability to unsubscribe from subsequent values in the sequence.
I'm unclear on how to implement "any subscriber can cancel" semantics through this API. Am I thinking about this in the wrong way?
Any input would be appreciated.
It's important to learn about Cold vs Hot Observables. If your Observables are cold, then their operations will not execute if you have no subscribers. Hence to "cancel", just make sure all Observers unsubscribe from the source Observable.
However, if only one Observer of the source unsubscribes, and there are other Observers still subscribed to the source, this will not incur a "cancelling". In that case you can use (but it's not the only solution) ConnectableObservables. Also see this link about Rx.NET.
A practical way of using ConnectableObservables is to simply call .publish().refCount() on any cold Observable. What that does is create one single "proxy" Observer which relays the events from the source to the actual Observers. The proxy Observer unsubscribes when the last actual Observer unsubscribes.
To manually control a ConnectableObservable, call just coldSource.publish() and you will get an instance of ConnectableObservable. Then you can call .connect() which will return you the Subscription of the "proxy" Observer. To manually "cancel" the source, you just unsubscribe the Subscription of the proxy Observer.
For your specific problem, you can also use the .takeUntil() operator.
Suppose your "final future" is ported as finalStream in RxJava, and suppose that "cancel events" are Observables cancelStream1, cancelStream2, etc, then it becomes fairly simple to "cancel" operations resulting from finalStream:
Observable<FooBar> finalAndCancelableStream = finalStream
.takeUntil( Observable.merge(cancelStream1, cancelStream2) );
In diagrams, this is how takeUntil works, and this is how merge works.
In plain english, you can read it as "finalAndCancelableStream is the finalStream until either cancelStream1 or cancelStream2 emit an event".

Categories