Of course, there is no a perfect paradigm.
Let’s have a look at this case:Example of a backpressured caseOur Observable is emitting so fast so that the observer has no chance to process all the data before receiving new emissions.
Then, the observerIt can happen for example when a sensor is emitting too many values and the data management requires extra time.
In order to avoid this case we need to establish a feedback channel where the observer (consumer) can notify the producer that it is ready to continue receiving data.
Rx provides default strategies, such as:The Buffer strategy keeps in a buffer the emitted data, so that the observer will be able to continue without loosing them.
A good example is data when reading a file.
The Drop strategy allows to discard the emissions the observer wasn’t able to receive.
A good example is sensor data managementThe Latest strategy is similar to the Drop one, but observer will receive last one to keep updated.
It is valuable as an improvement from the Drop one when using it for a sensor case.
Rx OperatorsThe operators are the operations which allow us to change the emissions before consuming them.
This is very useful to particularise the Observable for our case.
ReactiveX – OperatorsEach language-specific implementation of ReactiveX implements a set of operators.
Although there is much overlap…reactivex.
ioIn this link you can find all the operators classified by category.
Some of the most important are:Creating Observables: Operators that originate new Observables.
Some examples are the ones that were already presented, such us just.
Transforming Observables: Operators that transform items that are emitted by an Observable.
Map is one of the most interesting operators as it allows us to convert an item into another typeFlatmap transforms the items emitted by an Observable into Observables, then flatten the emissions from those into a single ObservableFiltering Observables: Operators that selectively emit items from a source Observable.
Debounce only emits an item from an Observable if a particular timespan has passed without it emitting another itemFilter emits only those items from an Observable that pass a predicate testCombining observables: Operators that work with multiple source Observables to create a single Observable.
Merge combines multiple Observables into one by merging their emissionsZip combines the emissions of multiple Observables together via a specified function and emit single items for each combination based on the results of this functionThere are a lot of more categories, such us conditional operators, boolean operators, mathematical operators… and many more.
Error handlingManaging the errors in reactive is as simple as considering as a new emitted item, but with an exception.
Actually, there are some error operators to take care of them, like:Catch recovesr from an onError notification by continuing the sequence without errorRx SchedulingNext point to take into consideration is how to manage threading.
Actually, we should consider where emissions should happen (e.
data coming from a network interface) but also where emissions should occur (e.
we might want to update the UI or save data into the storage).
We have two methods for taking care of it:subscribeOn → This method sets the thread where the observable is emittingobserveOn → This method sets the thread where the observer is consuming dataBest way to understand it is having a look into an example:We can see how threads are set and how different observers can subscribe from different threads considering what they need to do with the dataWe have a Schedulers class which provides us different threads:Possible threads from SchedulersThere is a specific library called RxAndroid for Android which also supplies access to Android threads:ReactiveX/RxAndroidRxJava bindings for Android.
Contribute to ReactiveX/RxAndroid development by creating an account on GitHub.
comThanks to this library we have access to the Android main thread to be able to change the UI from an observer:Why Rx Kotlin instead of RxJava?If we have a look at the library, we can notice that it is available for Java & Kotlin (even for other languages, like Swfit).
But which is the reason to consider Kotlin as the best language to use?Google announcementFirstly, Google just announced that they are becoming increasingly Kotlin-first for new Android features.
Actually, the whole Android community thinks on Kotlin rather than Java.
Secondly, Kotlin is a functional programming.
As soon as we understand the functional programming, we will notice how reactive programming and natural Kotlin code are quite similar.
In fact, best way is checking this example:As you can see, managing lists and observables in Kotlin are exactly the same.
And we can enjoy even the function extensions, such as toObservable (it converts a list into an observable).
Rx in AndroidThere are more libraries to get benefits from reactive in a easy way.
One example is Retrofit2-rxjava2-adapter:JakeWharton/retrofit2-rxjava2-adapterAn RxJava 2 CallAdapter.
Factory implementation for Retrofit 2.
comThis library allows to create network interfaces like:Example of Retrofit + RxBut that one is not the only one.
We have more like LiveData from Google, which allow us to use lifecycle-aware observables, so that lifecycle can handle the subscriptions automatically:LiveData Overview | Android DevelopersUse LiveData to handle data in a lifecycle-aware fashion.
comLiveData is a perfect candidate to connect our ViewModels to the UIBy using LiveData we can avoid memory leaks when we are not managing well the process of unsubscribing.
Anyway, LiveData is not replacing Rx as we don’t want to have at all levels in our architecture a dependency to Android.
Summing upReactive programming is used by a lot of developers because it allow us to use an architecture which can react at any level in a scalable way.
Even Google is betting for reactive paradigm with their LiveData.
There are a lot of pros like:ProsError handling is similar to normal eventsAsync operations are managed in a easier wayCode is easily testable with TestObservers & TestSubscribersWe can avoid memory issues produced by bad callbacks managementIt is quite similar to functional programmingBut we cannot forget that there are always cons:ConsThe learning curve might be slower at the beginningThe flows might be more complex and difficult to debug, at least for new developersWe can still have memory leaks if we don’t manage well the unsubscriptions or we change variables from different contextsFinally, did you remember the code at the beginning explaining the even case?.Let’s have a look at an easy fix for the problem with reactive:Now, the result will be:The number is EvenThe number is OddEnjoy when developing with reactive!.