Reactive libraries for Android

I assume that you are already familiar with RxJava (2.0). If not, I recommend you Christopher Arriola’s RxJava Android introduction about the differences of common Android programming and how reactive programming simplifies your daily business.
As a prerequisite for all upcoming reactive libs, you need to configure RxJava and RxAndroid.
1 2 |
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' implementation 'io.reactivex.rxjava2:rxkotlin:2.2.0' |
I configured RxKotlin as “on top” library on RxJava because it offers a lot of convenient extension functions for a smoother RxJava API interaction. Now let’s start which libraries enhance your reactive Android arsenal.
Retrofit
One of the most used library in Android development is the HTTP client library Retrofit. Due to its wide distribution and RxJava support, Retrofit is probably the (!) starting library to enter the reactive Android world.
Beside the Retrofit library itself, an adapter dependency needs to be included and a RxJava adapter needs to be attached to your former Retrofit client.
1 2 |
implementation 'com.squareup.retrofit2:retrofit:2.3.0' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' |
1 2 3 4 |
object Client : RestInterface by Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io())) ... } |
HTTP calls are IO operations which should naturally run in the IO Thread Pool and thereby dispatched to the RxJava IO Scheduler.
The interface definition can now be changed from Retrofit’s Call class to RxJava’s
- Single, emit one value or an error notification and close the reactive stream
- Completable, notification that my request succeeded but I do not want to process the response and close the stream
1 2 3 4 5 6 7 8 |
interface RestInterface { @GET("sprit/rest/2/petrolstations") fun petrolStations(@Query("uuid") uuid: Set<String>): Single<List<PetrolStation>> @POST("sprit/rest/2/report") fun report(@Body report: Report): Completable } |
If you are using the MVP pattern, your call could be look like this:
1 2 3 4 5 6 7 8 9 10 11 |
class ReportPresenter(private val view: ReportActivity, val report: Report) { fun sendReport() { Client.report(report) .observeOn(AndroidSchedulers.mainThread()) .subscribe { view.showToast(R.string.report_sent) view.closeView() } } } |
RxPreferences
There is barely a wide spread app which does not use preferences to customise the app experience. Thereby using a reactive wrapper around preferences becomes quickly a huge benefit.
1 |
implementation 'com.f2prateek.rx.preferences2:rx-preferences:2.0.0-RC3' |
In our app SprIT we encapsulated our preferences in an object class and initialise it via Application (if someone has a better approach, please let me know). Preferences.kt is equipped with convenient methods to access our used preference properties.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
object Preferences { lateinit var rxPreferences: RxSharedPreferences fun init(context: Context) { rxPreferences = RxSharedPreferences.create(PreferenceManager.getDefaultSharedPreferences(context)) } fun fuel(): Preference<Fuel> = rxPreferences.getEnum("fuel", Fuel.E5, Fuel::class.java) } class SprITApplication : Application() { override fun onCreate() { super.onCreate() Preferences.init(applicationContext) } } |
Our app uses a map view as main view. Gas stations are depicted via markers to show current fuel price data based on the preferred gas station type.

Map showing Benzin prices
If the user changes the required gas station type in his settings, the view shall be reactively updated.
1 2 3 4 5 6 7 8 9 10 11 |
class MapPresenter(private val view: MapActivity) { fun initMap() { Preferences.fuel() .asObservable() .concatMap { // Retrofit fetches price data for specified fuel type } .subscribe { // redraw markers } } } |

Changing preferences

Map showing now Diesel prices
RxPermissions
Handling permission results on your own is a pain in the neck. That’s why libraries like Dexter or android-permissions were created. Thank goodness that there is already a reactive equivalent. RxPermissions reduces the boilerplate code to a minimum.
1 |
implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.5@aar' |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class MapPresenter(private val view: MapActivity) { fun resolvePermissions(observable: Observable<Any>) { observable .compose(view.rxPermissions.ensureEach(Manifest.permission.ACCESS_FINE_LOCATION)) .subscribe { when { it.granted -> requestLocation() it.shouldShowRequestPermissionRationale -> view.showSnackbar(R.string.access_geolocation_rationale) else -> view.showSnackbar(R.string.access_geolocation_denied) } } } } |
If you are wondering what the ominous “view.rxPermissions” property is about then just wait for the next paragraph where we combine RxPermissions with another powerful reactive goody 😉
RxBinding
RxBinding is a library to wrap UI widgets in observables to subscribe to view events like clicks. We combined RxBinding with RxPermissions to trigger a full reactive click-permission workflow.
1 |
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1' |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import kotlinx.android.synthetic.main.map_activity.* class MapActivity : AbstractActivity() { private val presenter = MapPresenter(this) lateinit var rxPermissions: RxPermissions override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.map_activity) rxPermissions = RxPermissions(this) presenter.resolvePermissions(RxView.clicks(fab_zoom_to_location)) } } |
ReactiveNetwork
As responsible-minded app developers, a great UX is the essential thing. A good app is characterised by its capability to deal with bad network connections or offline states, briefly said “act globally, sync globally” by Arun Sasidharan.
A convenient way to deal with unstable network connections is ReactiveNetwork to alert a user at the right UI place at the right time.
1 |
implementation 'com.github.pwittchen:reactivenetwork-rx2:0.12.3' |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class MapActivity : AbstractActivity() { fun networkObservable(): Observable<Connectivity> = ReactiveNetwork.observeNetworkConnectivity(applicationContext) } class MapPresenter(private val view: MapActivity) { fun initMap() { view.networkObservable() .debounce(1, TimeUnit.SECONDS) .filter { !it.isAvailable } .observeOn(AndroidSchedulers.mainThread()) .subscribe { view.showSnackbar(R.string.no_internet_connection) } } } |
RxLifecycle
We all now the tricky part to attach and detach the view to our presenter in MVP. RxLifecycle can simplify that by declaring RxAppCompatActivity as super activity. A bunch of lifecycle extensions are added by RxAppCompatActivity which can be refined as well, e.g. by a concise onStart() lifecycle method.
1 |
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1' |
1 2 3 4 |
abstract class AbstractActivity : RxAppCompatActivity() { fun start(): Observable<ActivityEvent> = lifecycle().filter { it == START } } |
Now a presenter can subscribe and unsubscribe on specific lifecycle events, e.g. start.
1 2 3 4 5 6 7 8 9 10 |
class SettingsPresenter(private var view: SettingsActivity) { init { view.start().subscribe { Preferences.fuel().asObservable().subscribe { fuel.setSummary(it.label) } view.preferences.findPreference("pref_licenses").intent = Intent(view, LicensesActivity::class.java) ... } } } |
If we want to cut our subscription to network events as seen in section Reactive Networks or to stop waiting for a network response via Retrofit, RxLifecycle makes that straightforward.
1 2 3 4 5 6 7 8 9 10 11 |
class MapPresenter(private val view: MapActivity) { fun initMap() { view.networkObservable() .compose(view.bindUntilEvent(ActivityEvent.DESTROY)) .debounce(1, TimeUnit.SECONDS) .filter { !it.isAvailable } .observeOn(AndroidSchedulers.mainThread()) .subscribe { view.showSnackbar("No Internet connection") } } } |
1 2 3 4 5 6 7 8 9 10 11 12 |
class ReportPresenter(private val view: ReportActivity, val report: Report) { fun sendReport() { Client.report(report) .compose(view.bindToLifecycle<ActivityEvent>()) .observeOn(AndroidSchedulers.mainThread()) .subscribe { view.showToast(R.string.report_sent) view.closeView() } } } |
Further tasks like cleaning up you memory for given lifecycle events can be for sure conducted by RxLifecycle as well.
Conclusion
In case you had no clue about reactive Android libraries before, you now got a small insight how to make your apps for common Android tasks more reactive and thereby more efficient to embed Android SDK calls in your reactive workflow or reactive architecture.
Nevertheless, this was just the tip of the iceberg. If you want to get a full overview about reactive Android libraries, the following GitHub page is quite good: RxAndroidLibs.
Moreover, if you want to bring all of these libraries in a meaningful architectural order, I highly recommend you to learn more about the MVI pattern of Hannes Dorfmann
Cheers,
Stefan
Recent posts






Comment article