The way to data binding in Android

Today I wanted to share our experience on the way to MVVM (Model View View Model) pattern in Android project.

When the data binding library was introduced at Google I/O in 2015, it looked very promising technology and very awaited in our team. We have developers who developed in the past Windows applications using .NET framework using MVVM framework. They loved that pattern. And there were good reasons for it:

  • MVVM gives a clean separation between the UI and the rest of the application. Although it is still possible to bring the business logic in to the UI, because of powerful data binding expressions, but now the framework is on developers side to keep the things separate. And in most cases it is only up to developers to produce a clean code.

  • it improves test-ability. More code from UI is moved to easy testable View Model classes

  • it allows to work independently on UI and business parts. And such responsibility delegation becomes more clearer

But until 2015 MVVM was available mostly for Windows application developers, because it turns out that in order to implement MVVM pattern we know it now we need UI markup language and data binding expressions. Without these two components most common patterns developers were left with were MVP(Model–view–presenter) and MVC(Model–view–controller). In the web world things progressed faster, since already from the very beginning the main way how to create the UI was markup language (HTML) and some time later dynamic web emerged and along the way different engines that allowed developers merge data with the markup. But in the desktop and mobile application world markup languages and data bindings emerged only recently. First Microsoft introduced WPF (Windows Presentation Foundation) subsystem with XAML as a part of .NET framework. And later came out Android with its own markup language. About the same time when WPF was announced Microsoft architects Ken Cooper and Ted Peters announced MVVM pattern on their blog. And so MVVM era started in the Windows world, but Android developers had to wait little bit, before they could start to use MVVM framework.

So when the Android data binding (https://developer.android.com/topic/libraries/data-binding/index.html) and Architecture components (https://developer.android.com/topic/libraries/architecture/adding-components.html) were released, we decided to  give it a try. Until then we were already striving to separate UI from the rest of the application and therefore we were using MVP pattern in combination with Butter knife (http://jakewharton.github.io/butterknife/). And the first thing we noticed is that we don’t have to write so much boilerplate code to keep the UI and business logic separate. Now instead of Presenter, View interface and Activity that implements the View we wrote very thin Activity and Model View and made slight changes in layout files. So some of the user stories we could write faster. But it was not always the case. When we had to work with more complex views like map view we could not bind the data directly in the layout file, because of the lack of bindings. And so data binding was done in the Activity or Fragment. But from our perspective it was still  step forward because most of the views we used had bindings and if they didn’t we could implement simple Binding Adapters. Essentially we started to use data binding in layout markup where it was easy to use it and left the UI processing code in Activity or Fragment where it will have taken a lot of time to find a way how to implement the binding for the layout markup. So for our project MVVM worked out very well, but we should admit that there are projects where it will not bring much advantage. Therefore before you take a decision about the using of MVVM and data binding spend some time to investigate views and available bindings for them you are going to use in a project.

Choosing technologies while designing FitRadar app

When the idea about the FitRadar mobile app was clear and first user requirement draft created our team started to think about the software design. And one of the first questions that rose up was – what platforms should FitRadar app target. After analyzing the market we came to conclusion that the first version should be available on Android and iOS devices. Very naturally first idea was to go for cross-platform solution by using mobile phone WebView and implement the app as HTML5, CSS, Javascript app. We started to explore this approach and discovered that it will not allow us to cover all the user stories, and we rejected this approach, but we turned to Cordova mobile development framework and Xamarin, and very quickly realized some potential pitfalls, that could stop or slow down customer base growth:

  • right now the user requirements are mostly set by business owners and testers and not that much by potential users. But when the app will acquire the first customers their feedback will play big role in defining the app’s next version feature set. And even if cross-platform solution could satisfy are needs now, in the future we could run in to the situation where cross-platform solution won’t be able to provide the features, performance or design that users are asking for. And that in turn will lead the project to stagnation.
  • our app is not just an attachment to the main business but it drives the business, therefore it should meet the highest user expectations.
  • native apps usually have greater visibility at app stores and often get better user ratings and recommendations. This is essential for a good APP Store Optimization (ASO) positioning. Mostly because designing and building an app for multiple platforms with platform-specific user experience is too difficult

Once we agreed on the native approach we needed to decide with which platform to start and how to share the work done for one platform with other platform. We started to explore different approaches and technologies that would allow us to reuse the artifacts to some extent. As for now there is no magic technology that would allow us to convert Android app into iOS app or vice versa, therefore the approach we chose is to separate as much as possible the platform dependent code like UI from platform independent code like view models, business models and logic and data access code. And in such way we hoped that conversion of one language code base to another one could be be done faster. After exploring and comparing several approaches and technologies the several stood out among the others as the ones that work on both platforms:

1) Clean Architecture (https://medium.com/@dmilicic/a-detailed-guide-on-developing-android-apps-using-the-clean-architecture-pattern-d38d71e94029https://github.com/sergdort/CleanArchitectureRxSwift)

2) MVVM and databinding (https://medium.com/tech-travelstart/android-data-binding-mvvm-4888eb73a25d, https://codeburst.io/swift-mvvm-two-way-binding-win-b447edc55ff5)

3) RxAndroid / RxSwift (https://github.com/ReactiveX/RxAndroid, https://github.com/ReactiveX/RxSwift)

The main idea was to make the platform specific code as lean as possible and shared code as similar as possible on both platforms. It would allow us easy and quickly convert the shared code from one platform language to another. It turns out that the solution structure, app layers and the idea of common code and platform specific code separation was similar to one used by Xamarian (https://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/part_3_-_setting_up_a_xamarin_cross_platform_solution/). The idea that we could speed up development just by using one common language in this case C# was very attractive. And therefor we decided to revise our decision regarding the native approach. We talked to other software development teams that have experience in delivering apps using Xamarin and the here is what they shared with us: 

  • it works – you can create cross-platform app using one code base, but whether it saves time and money really depends on the project, because
  • the code you share between platforms is only about 50-70% from all the code, the rest is platform specific code and it has to be written for each platform separately
  • the development time for non out of the box platform specific features increases, since not all nice and useful third party libraries have Xamarin bind/port.
  • developers have much less help at their disposal to tackle a problem faced during the development. The Xamarin community is much smaller than Android or iOS. It means it could take more time.
  • the deployment of app even to a real device is much slower comparing with native app deployment. And again it means that the development process is slower.

And once again we came to the same conclusion – the cross-platform benefits in our project will not outweigh the potential risks it could introduce.