Flowable or Observable for network Requests? - android

I'm new to RxJava and currently, I'm understanding things through examples. One thing is always confusing me, and so far I couldn't find any better document to understand it clearly. Flowable Vs Observable, when to use which
As per my understanding, Flowable supports backpressure whereas Observable doesn't. Which means If you don't want to lose any stream (Such as UI events like mouse move, keyboard text entry) You should go for Observable.
If your emitter is emitting continues items, and you have a slower consumer, go for Flowable, It will manage out of memory errors by caching only limited amount of items
Alright, But in many samples and docs, I saw people using and recommend Flowable for network requests and disk operations. Including the googlesamples. But why? Why is Flowable best over Observable here? You will be hitting the API for a single response, and you would expect a limited set of result only, It is not like a continues emitter as the mouse move listener. So what makes it better to use Flowable here over observable?
Also, for a beginner like me, it would be helpful if someone could explain some of the common use cases to go for Flowable or Observable in simple words.

Related

RxJava - When and why to use Observable.share()

I've seen patterns like this:
Observable<String> nameChanges = nameDataSource.changes().share();
// One subscriber
autoUnsubscribe(nameChanges.subscribe(() -> { ... }));
// Another subscriber
autoUnsubscribe(nameChanges.map(...).filter(...).subscribe(...));
// autoUnsubscribe is called when the UI is torn down
My question is:
Why is it necessary to call share() whenever I want to listen to the Observable in multiple places?
Why is not share() the default behavior for all observables?
It would be nice if the code above worked the same even without .share(). I would not have to think about when I need to share an Observable, and when I don't.
Is it for performance reasons because having a single subscriber is a special case that can be handled more efficiently?
From the docs this is not clear to me:
share() returns a new ObservableSource that multicasts (shares) the original ObservableSource. As long there is at least one Observer this ObservableSource will be subscribed and emitting data.
There are two kinds of Observables: cold and hot. Cold Observables start producing items when there is an Observer to them and they do it on an individual basis. Subscribing with multiple Observers will result in multiple runs of the same cold Observable. An example of this is an Observable that issues a network request.
In contrast, a hot Observable can produce items with or without the presence of Observers. These Observables usually multicast the same items to all of their current Observers. An example of this is an Observable of button clicks.
To turn a cold Observable into a hot one, you can use publish() which will make sure only a single subscription is established to the source Observable no matter how many Observers there are. Thus, the chain will now act as a hot multicasting Observable from the Observers' perspective.
However, often it is not economic to keep an originally cold Observable running after all Observers of publish() have gone away, therefore the refCount() operator can be used to keep track of them and stop the source when there are no interesting parties left.
If your source is already hot, you don't need share().
Why is not share() the default behavior for all observables?
Actually, this property is one of the important contributions of the modern reactive programming paradigm: the distinction of the hot and cold Observables.
However, multicasting is expensive on itself because you have to keep track of the set of current Observers in order to notify them with new events, and this can lead to all sorts of logical race conditions to be defended against. A cold Observable is known to talk only to a single Observer so there is no need for the extra tracking overhead.
I would not have to think about when I need to share an Observable, and when I don't. I'm afraid that you will have to think when programming. ;)
In the above code, yes, sharing makes sense. But what if you we're updating something on the backend, using the same network and method call from two different points, updating with different data? You would have the same call with the same Observable, but you certainly wouldn't want to share the Observable instance (and the network call) because that means that all successive calls with data would be discarded in the favour of the first one. Or if you wanted to start a timer whenever you're subscribed, you again wouldn't want to share this with other Observables.
Also, it is much easier to add certain behaviour than to remove it. For example, if sharing was the default, and the second subscriber wouldn't want to share and removes the sharing - what about the third one? Will it share it with the first one or not? At that point the sharing property becomes the property of the Subscriber and not the Observable and you would have no clear way of knowing which one is shared and which one isn't.

Tactic for several different Room queries

While refractoring an app I decided to use room (and other architecture components). Everything went well until I reached database querying, which is async. It is fine by me, I can update views with LiveData callbacks.
But the problem arose with smaller queries following each other - with no thread restrictions it was easy, you could use variables straight away.
In legacy code there are plenty of setups, where quite many small data pieces are required one after another, from different tables. E.g., querying if item exists in one table, some calculations, querying another table, etc.
Disabling async requirement for queries is not an option, I prefer using Room as intended.
First thought was to nest callbacks, but it is too ugly.
Second thought was to query for all required data, start a method only after receiving all callbacks. It also does not sound nice and there are cases where one callback has data required for the other query.
Strangely I have not found any related forum posts or articles dealing with this problem.
Did anyone handle it already? Any ideas?
Most #Dao methods are synchronous, returning their results on whatever thread you call them on. The exceptions are #Query methods with reactive return types, such as Maybe<List<Goal>> or LiveData<List<Goal>>, where the methods return the reactive type and the results are delivered asynchronously to subscribers.
So, for cases where you have more complex business logic, you have three main courses of action (that I can think of right now):
Use RxJava and try to squish all that business logic into an observable chain. There are a lot of RxJava operators, and so some combination of map(), flatMap(), switchMap(), weAreLostWhereDidWePutTheMap(), etc. might suffice.
Do the work on a background thread, mediated by a LiveData subclass, so the consumer can subscribe to the LiveData.
Use classic threading options (e.g., IntentService) or more modern replacements (e.g., JobIntentService).

Why is it not possible to map BehaviorSubject to another BehaviorSubject

At least in mobile apps BehaviorSubject is used frequently, to model a property - it has a current value, which can be queried any time, and be observed.
Sometimes it's wanted to just transform a BehaviorSubject without subscribing to it. E.g. if there's class, that acts as an intermediate layer between several transformed BehaviorSubject and potential subscribers.
The issue I have encountered here, at least with RxJava2, is that applying operators on BehaviorSubject returns always Observable. So my intermediate layer can't offer anymore an api of BehaviorSubject.
A possible solution is to create new BehaviorSubjects and subscribe them to the original BehaviorSubject but this seems a bad idea overall, maybe I don't want to subscribe at this moment but only on demand, i.e. when the users of my intermediate layer actually needs these subjects?
In my case the context is an Android app with MVVM pattern, where the view model exposes BehaviorSubject to the views, which are for the most part derived from another BehaviorSubjects in the app. I currently went with subscribing in the view model, but I would like to improve this since the view model isn't really the consumer and shouldn't be subscribing to anything - the subjects should be activated when the view actually needs something from them.
And no I can't use only Observable in the view model as there are unit tests and some other calls that check for the value at a point, which can't be done using only Observable.
My main question is why is it not possible to simply be able to transform BehaviorSubject into another BehaviorSubject. A nice to have also, what is the recommended way to work with BehaviorSubject in the described context.
It would not compose properly, operators are final methods to avoid method dispatch problems. Plus, you'd create multiple entry points for and end consumer and possibly violate the Observable contract if you's onNext the transformed subject while also onNext the original subject.
But you can have multiple subjects merged together, each driven by its own respective events and the end consumers would receive events properly.
And no I can't use only Observable in the view model as there are unit tests and some other calls that check for the value at a point, which can't be done using only Observable.
Have you tried blockingFirst() to get the current value from a chain that starts from those original BehaviorSubject?
Otherwise, your design is unclear to me as it is too much focused on subjects other than being a single originator of some events.

What is the difference between EventBus and RxJava? [duplicate]

This question already has an answer here:
Android Pros & Cons: Event Bus and RxJava
(1 answer)
Closed 3 years ago.
I am confused about the difference between EventBus and RxJava in android. I need to implement one of them for my issue about notifying some components when some changes have been done, so that they can update their state.
Also, I read that EventsBus has became deprecated over RxJava and I don't know if this information is true or not.
EventBus and RxJava are different in their nature.
EventBus is just a bus as the name suggest - it provides the mechanism to subscribe and publish events to the "bus", without you caring how the wiring is done, what this "bus" actually is, etc. In the context of Android, the EventBus is just an easier way to deal with sending and receiving Broadcast messages with less boilerplate.
RxJava on the other hand is much much more powerful than that. Yes, you can subscribe and publish events, but you have far more control over the process - frequency, on which thread everything happens, etc. The main power of RxJava (in my opinion) is that you can manipulate the data being published very easy, using some of its tons of operators.
To sum up - if you only care about publishing some events and performing some actions when received - you'd probably be better off using the simplest of the two, namely some kind of Bus, or even plain old BroadcastReceivers. If you will also benefit of transforming the data, handling threading or simplified error handling - go for the RxJava approach. Just keep in mind that RxJava generally has a steep learning curve, so it takes some time to get used to its concept.
To understand RxJava, think of a list. Today manipulating a list like transforming, splitting, merging can be done easily using functional methods (map, groupBy, etc). RxJava uses the same principles except that its main target is not list but stream. Stream is asynchronous, often live data such as websocket channel or online movie.
Event bus comes from the needs to decouple classes which in Android are often bound with life cycle. Tight coupling of network callback and Activity's Views as an instance, has been a cause of numerous null pointer exceptions. Event bus with its publisher-subscriber pattern alleviates this issue.
How does it get mixed with RxJava ?
To begin RxJava incorporates Observable pattern. Here an Observer watches an Observable and reacts when an event arrives. Observable has several sub-classes, among which is Subject that has the properties of both Observable and Observer. Since it works by trapping an event and publishing it to subscribers, it technically functions as event bus.
Is it wise to use RxJava as event bus ? No. RxJava would introduce unnecessary complexities for simpler purposes. Only use it if the app does manipulate streams. For example pairing frames from a movie stream and subtitles from another stream. If the app simply consumes a REST API and needs to decouple the callback from activities/fragments then event bus is enough.
Live #Vesko wrote, RxJava and event bus differ in their nature and may serve to solve different problems. Nevertheless, there are some scenarios in which both of them can solve the same problem (although at different costs), and this might be the reason for why many people confuse these two concepts.
RxJava is conceptualy similar to Android LiveData that was released not so long ago, and to better understand these concepts, as well as event bus, I suggest you read my post. In the post I go over these very concepts, describing the scenarios in which we should use one over another and the pros and cons of using one rather than the other. I think it may be useful to you:
When and why to use LiveData
If you want to fetch data from sever and update UI, use RxJava + Refrofit. If update UI or do some operation without fetching data, EventBus is enough.

Android Pros & Cons: Event Bus and RxJava

I have been using Event Bus in my apps (i.e: greenrobot/EventBus). But I find some disadvantages in using Event Bus:
Chaining tasks execution is difficult
A lot of classes to represent events
Less clear code (well, it's still possible to trace, but not as clear)
I have been researching for new techniques to deal with this problem. And I read quite a bit about RxJava and wonder if it could be a solution.
So my questions about RxJava (based on what I have read recently):
Could RxJava observer be registered at any time? So not just when creating the Observable. With EventBus this is possible, I could subscribe at any time, not just when the Observable is created.
How do you handle two or more publishers publishing the same type of event (e.g: navigation event)?
Tightly coupling the publisher(s) and the subscriber, means that I have to explicitly specify the publisher(s) every time. So I have to worry not just with the type of events, but also the originators. With EventBus, I only need to worry about the type of events and not the originators.
1) Once you have an instance of an Observable, you can subscribe to it at any time and from any thread, even concurrently.
2) We usually merge the streams of multiple observables via Observable.merge() or use a serialized PublishSubject.
3) If you observe an Observable, there could be dozens of upstream operators and sources involved, but you'll get a sequential stream of values no matter what. You only need to get a hold onto an Observable representing some source of events and the observer doesn't need to know if the event was merged, filtered, made a roundtrip over the network and got delayed before arriving in your onNext() method. You can naturally implement or use some lookup service that will get you an Observable to reduce the coupling, but with RxJava, coupling is not usually an issue.

Categories

Resources