Where are the big UseCases to need RXJava in Android - android

this is more an architectural question or also maybe a question of point of view.
Many Android libs have an reactive approach in there APIs. e.g. Volley
, Volley have a nice JsonObjectRequest to put it into a RequestQueue and in the callback onResponse you can handle the response.
Or in Picasso you have also an async call to just load the picture in a given ImageView.
In the new Persistent Tool ObjectBox for Android you have also an reactive approach to set and query data from the database.
So my question is, where are the great needing of RXJava in Android? In which UseCases is RXJava essential?

Reactive is not the same as "observer pattern". Call backs are not the same as reactive. Custom-fitted call back interfaces are much more specific and not as easy to generalize as the reactive implementation of RxJava.
RxJava follows the observable contract, meaning that its behavior is consistent within itself, and that behavior is readily generalizable.
RxJava uses a basic set of operators, with Java generics, to provide a very rich customization portfolio. An Observable<CustomJsonObject> is known to behave in the same way as an Observable<Long>.
Given (1) and (2), you will find that you can compose reactive operators to get customized behavior. Hence, customJsonObjectObservable.distinctUntilChanged() will behave in the same way that longObservable.distinctUntilChanged(). You don't need to create a custom class that stores the previous item for comparison, as the operator takes care of that for you.
Introducing the passage of time or multiple threads is done using operators, and these aspects are also composable. The interval() operator provides periodic updates, the buffer() operator collects data that arrives within a period, and the timeout() operator monitors data and announces when it is not present in a time period.
Point (4) is probably the biggest win for RxJava. Reasoning about the passage of time, especially in the presence of multiple threads of control, is very hard. RxJava brings those difficult areas under control. Hard problems are not quite so hard to solve, and very hard problems can often be decomposed into areas with easier solutions.
Volley does not address the hard issues. It provides asynchronous responses, and addresses only a fraction of item (1) above. It does not address (2), (3) or (4).

Related

Switching from coroutines(kotlin) to isolates(dart)

I have an Android app made using Flutter.
Currently, most of the business logic runs on Android native Kotlin, but I love Dart so I am considering moving a lot of the logic to Flutter.
Is there any concern about converting Kotlin's coroutines to Dart's isolate?
There are no general concerns that I'm aware of. Although there are some points that you need to consider before doing the change.
The concurrency paradigm changes from multithread to single thread. This means that you should not think of changing coroutines to isolates, since you will not be using isolates so often or for the same purposes as coroutines.
Isolates are used for "extreme/unique" cases, if you want to perform a long running operation, you normally shouldn't opt out for an isolate, you should perform that with the simple async/await.
It's simpler to use async/await since you don't have to worry about resource allocations or race conditions, but at the same time it allows you to do "dirtier" things, to the responsability is on you.
Last thought on Isolates: they are a separate process so communication between isolates is only done through messages, so basic data should be passed between them and that could give you some headaches if you want to return some big data. (Of course everything is possible with serialization)
Hope this helps you to choose, if not, feel free to comment and we can discuss this further.

Ways to create a layer of abstraction on top of a reactive database?

I'm fairly new to reactive programming, and I can't seem to wrap my head around how to abstract a reactive database so that I can easily swap them out in the future.
The current target database is Realm, and it's tempting to simply reference them in my DAO classes, which communicates with my repository classes. However, after some thought, I should probably create a layer of abstraction on top of the DAO's so that I don't have a hard dependency on Realm. In this case, it'll be more or less forwarding Realm's inputs and outputs. However, I can see where I might try to make a standard sqlite database reactive.
But before I go down this path, I was wondering if there were better alternatives from people who do have experience in this subject.
and I can't seem to wrap my head around how to abstract a reactive database so that I can easily swap them out in the future.
You need a common abstraction that represents the latest value of multiple event emissions.
Potential candidates are io.reactivex.Observable<T> or LiveData<T>.
The current target database is Realm, and it's tempting to simply reference them in my DAO classes, which communicates with my repository classes.
It's tempting until you realize that a Realm instance is thread-local and reference-counted, so if you do that, you won't be able to know when to close the Realm (unless you pass Realm to each of your dao.find*( methods, or create a ThreadLocal<Realm> yourself manually so you can keep track of when to close it.)
In this case, it'll be more or less forwarding Realm's inputs and outputs. However, I can see where I might try to make a standard sqlite database reactive.
While Room and SqlDelight provide support for that, you can look around in this repo of mine for how you can create a simple wrapper over SQLite yourself.
But before I go down this path, I was wondering if there were better alternatives from people who do have experience in this subject.
If you want to make Realm "independent of being Realm" and available for observing without relying on its lazy-evaluation, you can put Realm on a background looper thread (HandlerThread) from which you map out the items when you detect change.
These RealmResults on this background looper thread must be kept in a Set to keep strong reference to them in order to retain the ability to listen for changes.
If you stop observing ALL the RealmResults you've opened, then you potentially want to close the Realm automatically.
While I don't really touch the project anymore, you can look at Realm-Monarchy (by me) which does exactly what I mentioned above: wrap RealmResults into a LiveData<List<T>> so that it can be swapped out with anything else (including for example Room). You can dabble in its source code if you like.

How to use Realm "live" objects and keep database layer decoupled from other layers(business, UI, etc)?

I'm playing around with Realm for Android.
I like the auto-updating objects idea, but I have a concern about it regarding software architecture.
I've seen that many proposed architectures specify a layer to handle data/database access, and ideally the higher layers will not know specifics about the database implementation. This will help with maintainability, modularity, etc.
When you use Realm objects, if you want to take advantage of their auto-updating property, the most common way I can think of doing that is having those objects on Activity/Fragment code. Now let's suppose that the user just edited data on screen(that is represented by a realm object under the hood) and is saving these edits. If you call this object's setter, that will actually be a database operation and you will need a transaction. By creating a database transaction on activity/fragment code, architecture falls apart, as you are making your UI/business layers aware of database implementation details.
My question is: how to take advantage of Realm auto-updating objects in a way that doesn't hurt architecture?
Side note: I've used Realm in a recent app and for every query, we had to copy the results to unmanaged objects so that we could send them up to UI/business layers. I don't think that is the best strategy out there, as we could not use Realm to its full potential.
After some research, I came to the conclusion that indeed one needs to make a major choice about integrating Realm to an app: Safe integration x Deep Integration.
Safe Integration
Here you will isolate Realm from the rest of the app code. In order to do that, you won't be able to use the auto-updating/zero-copy of Realm. Instead you will have unmanaged copies, to make sure that anywhere the objects are accessed, you won't have problems with different threads accessing the same objects. Testing is easier this way.
Deep Integration
Here you will use Realm to its full potential, lazily loading data when requested. The downside is that other layers of the code will be aware of Realm, in the sense that they will need to make sure that managed objects are not accessed by different threads. This options potentially involves heavy refactoring if you are not starting a new app, but will bring the performance benefits of the zero-copy approach.
My answer is based on these articles: https://medium.com/#Viraj.Tank/realm-integration-in-android-best-practices-449919d25f2f#.ms3nenq0m and https://medium.com/#Viraj.Tank/deep-integration-of-realm-in-android-production-code-part-2-with-mvp-4cf44ab6289d#.qq4p12mtw

Android models layer design, synchronized or asynchronized

When I design models layer, there are two way to design my interface. Synchronized or asynchronized.
A. asynchronized design:
interface Callback<T> {
void success(T t);
void failure(Throwable err);
}
interface UserAPI {
void getProfile(Callback<User> callback);
}
B. Synchronized Design
interface UserAPI {
User getProfile();
}
They both have some benefit. A is non-blocking, the UI layer can use it directly. B is blocking, but it is easy to test, the design is much simple, but the UI layer should make a thread to handle it.
I really care about agility development, easy to maintain, keep the whole project neat. Which design should I use?
Ultimately, this is more a question of what you want your API to accomplish, how easy is it to use, performance impact, etc. Asynchronous designs, when done correctly, can help with some performance and API usage restrictions. But, they also tend to be harder to implement correctly and even understand by end users. Synchronous APIs tend to be easier to understand, but come with more restrictions (as you noted with use on the UI thread.) As far as backing implementation, async can also be harder to understand and maintain. I don't think agile development models really influence this, as well as the project maintenance. I would try to ensure those working on it (employees, open source contributors, etc.) are good developers who understand both approaches, write easy to understand and well structured code, and understand the goal of the API.
My recommendation: implement an API which has both async and sync versions available. Maximum flexibility, best of both worlds. Just be sure to document both sets of APIs so users know the semantics of using both.
I think it depends on a particular task. You can't choose either way for the whole project, as it usually consists of multiple parts. As a general rule, each task should be reduced to the synchronous behavior whenever it's possible, for the sake of simplicity.
If an operation is done over a fixed period of time and isn't much
longer than other operations, you can call it synchronously in the
UI thread.
If the execution of an operation may take long or unlimited period
of time, or it depends on some external conditions (e.g. network
connection, system load) and doesn't interact with the UI layer, then I'd use the synchronous design in a background thread.
If the same operation as in the previous paragraph causes updates to the GUI, then obviously the async design should be implemented.
Internal use
I would say it depends on how you will be using this API interface. If it's going to be used internally then it's a matter of where would you like to handle background threads. It's completely up to you.
Published API
In case your API is going to be published then actually it depends on developers needs. Some like to handle threading by them self deciding if it's going to be a single thread queue, multithreaded simultaneously solution or combination of both. For them SYNC API is perfect.
On the other hand some developers may not care about threading and just want get the result as easier as possible. For them ASYNC is perfect.
Recommendation
So it's seem that most probably you will have to implement both. It's most appreciated by developers and reach wide audience. For example have a look at one of the most popular network API Retrofit. They probably had the same decision to make and they implemented SYNC and ASYNC.
RETROFIT SYNC EXAMPLE
#GET("/user/{id}/photo")
Photo getUserPhoto(#Path("id") int id);
RETROFIT ASYNC EXAMPLE
#GET("/user/{id}/photo")
void getUserPhoto(#Path("id") int id, Callback<Photo> cb);

Content providers: wrap with a static facade?

I am going through a bit of a design dilemma, I have been targeting Android 2.3.3 and have a custom implementation of a ContentProvider. I then have a class of static methods to abstract the Content provider - providing me with objects representing each entity (row) based upon my query. For a while I was very comfortable with working like this, until I started wanting to use the whole collection in a number of places, for performing "hit tests" and drawing to the screen. I then had the headache of keeping my object representations up to date, and at this point have decided I need to step back and reconsider where to take this.
As I say, I am presently using 2.3.3, and realise that in 3.0 CursorLoader overcomes a lot of the problems I have encountered. I still need to support smart phones though, so unless there will be a backport I cannot do this.
As an interim solution I started to register notifyChange listeners so that I can rebuild a collection with my original query, but this strikes me as very CPU intensive and potentially slow. I haven't yet decided whether I should roll back from using my static facade and instead use the now obsolete managedQuery call from Activity.
I therefore have two questions:
1) Is there a preferrable way to avoid the issues with working against a collection based around a contentProvider?
2) Have you any advice on working with raw cursors in an activity? Should I be making objects out of them or working with the cursor as-is? I certainly feel they should be in an AsynTask while performing the query, but after that can I use them anywhere?
Ok, well I came to a decision and it works reliably.
1) Is there a preferable way to avoid
the issues with working against a
collection based around a
ContentProvider?
I have decided that the approach I took was correct; In my situation it is preferred to make a cache rather than maintain a cursor (managed or not) to the ContentProvider; this allows me to reuse methods and reduce the amount of code that requires testing. NotifyChange listeners are important until working on 3.0+ and that means I should guarantee the NotifyChange is called - another argument for centralising all of this code, so that it indeed triggers the changes when expected.
2) Have you any advice on working with
raw cursors in an activity? Should I
be making objects out of them or
working with the cursor as-is? I
certainly feel they should be in an
AsyncTask while performing the query,
but after that can I use them
anywhere?
In my use case I have decided it is a matter of thinking about what it is I am planning to create - avoid unnecessary work, with respect to returning unnecessary rows & fields and potentially creating unnecessary objects. If I am looking to create a map of entry names and entry IDs then I shouldn't be getting all of the other fields too. Abstracting from the collection is good but it must be lightweight and take in to account how the data is used - whether it is a one-off or may be used repeatedly. It is important that it is written for performance rather than completeness.

Categories

Resources