Skip to main

6 RX-friendly libraries for Android

by Ziemowit Pazderski

6 RX-friendly libraries for Android

So, you are an ardent believer in the gospel of Reactive Revolution. You know your flatMaps and switchMaps, breathe in zips, exhale in debounces, you start your Singles and Maybes with a capital letter in every single sentence, but one thing bothers you - there actually exists a part of the (programming) world that is not yet reactive!

Well, despair no more, for here you will find a selection of Android libraries that will RX-ify even the ugliest, plainest procedurally projected piece of programming.

Copy link
1. RxKotlin

RxJava bindings for Kotlin 

Yes, we all know this library, but there is certain propriety about writing these articles. Some formalities can’t be omitted - when writing about adding RX-value to applications written in Kotlin, every Uncle Bob-fearing programmer knows that a library actually called RxKotlin goes first, no contest. 

RxKotlin is actually just a set of useful extensions, instead of a proper library - mostly various castings and conversions. Close to 50% of the API count are just different variants of toObservable, toFlowable, and toCompletable. Still, it’s very soothing to know that with any standard, procedural object you are just one method away from your safe RX haven.

Copy link
2. Lives 

RxJava operators for LiveData

Back in the ancient past of 2017, Google introduced MVVM as the suggested architecture for an Android project. While currently it is (Maybe) being slowly phased out in favor of MVI, still a lot of projects were created according to this design. Projects often too large to be rewritten, so you are forced to live with all these LiveData, a travesty of a proper RX object, with their nearly non-existent set of reactive methods. But why ride a Buick if you can ride a Ferrari? 

Or, in this case, at least paint your Buick so it sort of looks like a Ferrari.

For example:

liveDataVar
.distinctUntilChanged()
.map { /* do the RX magic */}
.nonNull()
.take(3)

Copy link
3. RxBroadcastReceiver

RxJava binding for BroadcastReceiver

A simple tool for a simple task - instead of creating a boilerplate class extending BroadcastReceiver you need just a few following lines of code.

RxBroadcastReceivers
  .fromIntentFilter(
      context, 
      IntentFilter(LocationManager.MODE_CHANGED_ACTION))
  .subscribe {
      // react to broadcast
}

Copy link
4. RxRelay

Combining Observable and Consumer

Good ol’ Jake Wharton - as always taking an existing imperfect concept and putting his spin on it, so it makes a programmer’s daily struggle just a little bit easier. Timber, ButterKnife (R.I.P), ThreeTenABP (that’s a lifesaver), and Maybe one or two more 🙂 We all know, cherish, use and abuse his work. But this time? An object that is both Observable and Consumer... did Jake just invent a Subject?

Not quite. Relay is indeed a Subject, but a limited one - it can’t call onComplete or onError. That means it will never end. Never stop the signal, regardless of what you will be feeding it, including invalid data. Very useful for “bridging the gap between non-Rx APIs”.As with Subjects, we have:

  • BehaviorRelay - observer gets the last item before subscription plus all the subsequent ones

  • PublishRelay - observer gets only items emitted after it subscribes

  • ReplayRelay - buffers and emits all items to all observers

No AsyncRelay, since it requires a completion, which Relay by design doesn’t do.

For code samples, please check the library’s GitHub page.

Copy link
5. RxDownload

Classic file downloader

With everything being in the cloud now, and likely to stay there, instead of a smart sync or REST API call, sometimes an app needs to perform an old school download. Wouldn’t it be nice if there was an RX Army Knife for that as well?

Example (from the library’s readme):

disposable = url.download()    .observeOn(AndroidSchedulers.mainThread())    .subscribeBy(        onNext = { progress ->            //download progress            button.text = "${progress.downloadSizeStr()}/${progress.totalSizeStr()}"            button.setProgress(progress)        },        onComplete = {            //download complete            button.text = "Open"        },        onError = {            //download failed            button.text = "Retry"        }    )

Copy link
6. MvRx

MVVM with an MVI twist

That’s all nice if you are civilizing an old-school project, but what if you start a new one? You’re all familiar with MVVM, looking perhaps for something better, but MVI doesn’t feel battle-proven yet? Well, in that case, how about employing Airbnb as your quality assurance team and giving their praised solution a try? Formally it is an MVVM, but with its immutable state and Single invalidate method called after state is copied it smells suspiciously MVI-like. Covering this entire library would exceed the scope of this entry, so, for now, it is just an FYI that it is there.

Copy link
Summary

As you can see, there are plenty of RX-friendly libraries that help to civilize those non-RX projects. With their help, you have hopefully been able to get your project a little closer to completion.

And that’s before we take a closer look at the elephant in the room - the co-routines and the RX support they provide. Describing that in detail would require an entirely new article, so stay tuned and in the meantime, you can check out the Kotlin co-routines module on Github.


IntroductionArticle

Related Articles