Tactic for several different Room queries - android

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).

Related

Understanding reactive

Recently kotlin flow is gaining a lot of attention. I have never done any reactive programming before so i thought now is a good time to learn it. Even though I have access to books and some articles I could not understand how to integrate it say on an existing app that does not have any rxjava. I tried looking for some sample but the only thing they would give me is very basic. Im really confuse about this reactive programming thing. For example, I have a list that I needed to get on database. Why would I use flow to get that data? If I visualize it as streams, that would give me one data each. While if I get that list I could get the whole list without waiting for each streams to come if I had use flow. I read a lot of articles about this kotlin flow, even rx java. But still, I wanted to understand why streams and how is it any different from other way like the example I just gave?
For example, I have a list that I needed to get on database. Why would I use flow to get that data?
Well, that depends entirely on what you are using to access that database and how it uses Flow.
Let's suppose that you are using Room from the Android Jetpack. In that case, you can use Kotlin coroutines in two ways, via suspend functions and via Flow:
#Query("SELECT * FROM stuff")
suspend fun getStuff(): List<Stuff>
#Query("SELECT * FROM stuff")
fun getStuffNowPlusChanges(): Flow<List<Stuff>>
In both cases, Room will do the database I/O on a background thread, and you can use coroutines to get the results on your desired thread (e.g., Android's main application thread). And initially, the results will be the same: you get a List<Stuff> representing the current contents of the stuff table.
The difference is what happens when the data changes.
In the case of the suspend function, you get just the one List<Stuff> from the point when you call the function. If you change the data in the stuff table, you would need to arrange to call that function again.
However, in the case of the Flow-returning function, if you change the data in the stuff table while you still have an observer of that Flow, the observer will get a fresh List<Stuff> automatically. You do not need to manually call some function again — Room handles that for you.
You will have to decide whether that particular feature is useful to you or not. And if you are using something else for database access, you will need to see if it supports Flow and how Flow is used.

Flowable or Observable for network Requests?

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.

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.

Best way to structure code when using asynchronous methods (e.g. auth retrieval)?

I'm working on an Andriod app. I was examining my work from a high-level perspective, and there seemed to be a very high branching factor of potential [auth-based] crashes that could occur stemming from the fact that authorization is asynchronous using Firebase.
My attempt at solving this (simplistically put) was to put pretty much all my code into the callback of the Firebase auth result (but then I had issues with race conditions related to the Google API Client [I use location] connection callback, along with other small issues).
After doing what I could to make it as watertight as possible, I'm a little dissatisfied with the way my code is laid out in my project. E.g. In my MainActivity's onCreate method, I wish I could just lay everything out linearly to be executed one after the other (but I am aware of the UX drawbacks of not having things being done asynchronously).
Given this, I'm wondering if anyone knows of any better ways to do this or best practices when it comes to this sort of thing. Is the best solution just to put all the code into the callbacks of methods on which it depends? Or is there something I'm missing?
Thanks
yes there is , your structure is asynchronous in nature.To avoid race conditions every condition must trigger accordingly. The glorious concept of promises perfectly does this job for you.Promises return an object…which promises to do some work.This object has separate callbacks…for success and failures.
This let's us work with asynchronous code…in a much more synchronous way.…A really nice feature is that promises…can be combined into dependency chains. Which simply means execute this, if that happens or fail that. Please consider using rxjava or rather rxandroid which embodies the notion of observable.Observables can be used to model events, asynchronous requests, and animations.
Observables can also be transformed, combined, and consumed.
is the best solution just to put all the code into the callbacks of methods on which it depends? well like you said it depends , what you should is to separate tasks into single dependencies not one big monolithic callback.

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.

Categories

Resources