March 21, 2016
Take 3, Scene 5: Clean Android Architecture Based on ReactiveX
For a very special international episode of Take 3, 3Pillar's Karoly Szanto and Ciprian Grigor join us all the way from Romania to take a look at Clean Android application architecture based on ReactiveX.
ReactiveX is an API for asynchronous programming with observable streams. It's a combination of the best ideas from the Observer pattern, the Iterator pattern, and functional programming, and it is extremely flexible - it's cross-platform compatible, and it's usable for front-end and back-end development.
- Karoly and Ciprian give a background for ReactiveX and its advantages over other alternatives, as well as discuss which familiar companies use it and how they put it to use
- Both of them break down the concept of clean Android application architecture and describe how ReactiveX can be used to set one up
- The two of them describe their recent experience of presenting a workshop on this topic at the MobOS conference in Romania
About the Guests
Karoly Szanto is a Technical Manager, based out of Timisoara, who works on bringing 3Pillar's Android projects to market. He works with different teams of architects and designers to choose the right technology stack for each individual project.
Ciprian Grigor is a Technical Manager and an Android Competency Center leader that mentors teams in building Android applications at 3Pillar. He loves to share his knowledge and inspire teams to pursue seamless mobile user experiences. His interests are clean architecture, reactive programming, material design, and smart devices.
Read the Transcription
Julia Slattery: Today we're talking about Clean Android Architecture based on ReactiveX. Let's start in reverse order here. What is ReactiveX and what are some of the companies out there that listeners may have heard of that use it?
Ciprian Grigor: This is a big question, so I will divide it in two. First, what is ReactiveX? By definition, it's the API of asychronous programming with several streams, but it is much more than that. It's a way of thinking based on reactive programming, which is a programming paradigm oriented around data flows and the propagation of change. The inventor of it is Erica Meyer, who led the team in the time when she was working at Microsoft and put the base for the Reactive extentions for .NET. Later, this was implemented in Java by Netflix and has been used by SoundCloud, Trello, Square, and Couchbase, which is an SQL database. All of those companies are using this both on the server side and in mobile applications.
Karoly Szanto: As Ciprian said, ReactiveX is just a particular implementation of the Reactive programming paradigm, but on the other hand, it's more than an API. It’s considered to be an idea and a breakthrough in programming that has inspired other APIs and frameworks. For instance, the version number one of the Reactive streams API came out, which is an initiative to provide a standard for asynchronous stream processing, and this API was proposed to be included as a new idiom in Java9. And as I said, it's been heavily influenced by ReactiveX.
Julia Slattery: Okay great. So for those who may not be familiar with the concept, what is a clean android application architecture?
Karoly Szanto: Clean architecture in general has a clear objective and that will be the separation of concerns. This is usually achieved by dividing the software into layers. So for instance, you would have a layer for business rules, one for data, another for UI, so on and so forth. So following these basic principles, you should end up with a codebase properly split into individual and testable modules.
Basically, you would have the module for the business logic, which can be tested in isolation of the UI, the database, or the web server it’s getting data from. And on the other hand, your project should also end up decoupled and being independent of any external frameworks. Clean architecture in Android is just making sure that you follow these rules of clean architecture in the context of the android framework.
Ciprian Grigor: The one thing that I would add is that one way to measure clean architecture is how easy is it to test by using unit tests and have a very clean separation of concerns as a result.
Karoly Szanto: I would say that apps are highly interactive or are becoming highly interactive, with a multitude of UI events related to data events. They are becoming more and more real-time. For instance, modifying a single form field can automatically trigger or save to the backend, or liking a tweet can be reflected in real-time to another or the same app running on another device. So apps are relying on a large number of real-time events of every kind, which enable highly interactive experiences for the users. We need tools to properly deal with that data, and reactive programming is considered to be the silver bullet in this case. ReactiveX, and in particular, RxJava helps you to achieve that on Android.
Julia Slattery: So how can ReactiveX be used to set up a clean Android application architecture?
Ciprian Grigor: One of the things that Karoly mentioned was the separation of concerns. What the Reactive extension brings is the asynchronous model of programming, meaning that we can separate this threading concern through this library and make it very declarative. This allows us to use less code, to have a very easy concurrency model, and also to have an error handling in computation, because error handling in asynchronous computation is very hard to do.
Karoly Szanto: I would like to add a few things to what Ciprian said. You could achieve the separation of concerns following the Reactive way by exposing observables from each module. So for example, instead of having a deep understanding or deep knowledge of how a certain implementation of an HTTP client who fetches data from a Web server, you could just subscribe to an observable that you know will publish the desired results once it's done, without you needing to know anything about the underlying implementation of it. So by that, you could achieve a clean separation of concerns.
Ciprian Grigor: Karoly mention observables here, because ReactiveX is just like an observable on steroids. It is the single most used interface in Reactive for services and all the communication goes through this common interface. So that makes it very easy to compose several streams of data and not have to deal with different interfaces and hard-to-compose services.
Julia Slattery: Are there alternatives to ReactiveX out there that you've worked with as well? And if so, what are the advantages of ReactiveX compared to the alternatives?
Ciprian Grigor: On Android, I don't think there is an alternative or a single alternative to that. However, you can see ReactiveX as a replacement for an asynchronous task, which is a core concept in Android – like executing an operation on the background thread and getting a response on the main thread or as a replacement for an event boss library. One example would be Auto made by Square, in which you register to events and get notified when events happen.
In the land of Java, not really mobile, we have executors and futures that are similar in a way, but the difference is that with futures and executors, you get a single execution of unit. With observables, you get multiple executions and you are notified when that execution has been completed.
Also, Karoly mentioned the Reactive streams, which is a way to process stream input without back pressure and concurrency problems. The thing with Reactive streams is that they don't support flat-map, which is a basic operation in Reactive for composing multiple observables generated from one stream to other streams. Actually in ReactiveX, Reactive streams can work with each other because they have like the same core concepts, and the second version of the Reactive extension is implementing reactive streams as well.
Karoly Szanto: At a higher level of what Ciprian said, and in a less specific way, ReactiveX comes with an API which, at its core, has asynchronous streams of data. It offers a toolset and operations to process the data and the streams, to combine them together in an intuitive manner, and it also raises the levels of reactions so you can focus on low-level threading and the synchronization of data, convoluted callbacks and all that. It just makes it very easy for you to work with.
On the other hand, as an alternative to ReactiveX, I have Eater because the average Java is just the Reactive extension for the Java Virtual Machine. Although, as I mentioned in the introduction, there is the Reactive streams API which, again, is a standard Reactive extension for the JVM and it might become the standard in the future. But it was just recently launched, version 1.0, and I haven't tried it out on Android.
Julia Slattery: So the two of you recently presented a workshop on this topic at the MobOS conference in Romania. What did the workshop consist of and how did it go?
Karoly Szanto: The workshop was an introduction to Reactive programming with examples of how you can do Reactive programming using RxJava. We also went more specific and we talked about how you can do that in Android. It was focused on us helping people get a pragmatic understanding of RxJava and how they can apply it to their projects. So basically, the participants and us together developed - step-by-step - a project using Rx. The exercises that we set up was not Rx, so the participants only had to write a small snippet of code consisting of ReactiveX operators solving a certain problem.
Ciprian Grigor: Regarding the workshop, we made it a series of exercises. Each exercise has a D2D approach where we will have written the test for them and they had to complete the code so that the test will pass. That also proved the architecture in a way that the implementation was testable. In this application that we made during the workshop, we used several libraries that provide us with ReactiveX interfaces, and it is very easy to compose those services.
Karoly Szanto: All in all, the workshop went well. Of course, there were people who were less prepared for the workshop and people who had a better understanding of software development in general. So some of them did find that the information was a bit too much, but others found it to be exactly what they were expecting. The feedback was pretty good in general; people loved the way that the workshop was split into covering theoretical aspects, and the fact that they got to get their hands dirty with some coding, and the fact that we did help them get a pragmatic understanding of how exactly they can use this new paradigm in their everyday work.
Ciprian Grigor: Yes, the Reactive program paradigm is pretty hard to understand if you are coming from imperative programming. Still, we made the workshop in a way that we exposed the problem gradually and then we advanced through the concepts. And I want to mention that the participants were almost always ahead with the problems, figuring out what would be the next thing to solve. We had a very engaging audience.