This knowledge is mainly taken from the research and the work I've done for my current project. At the beginning there were big discussions if we should do plain old Java or use Scala for the app. Fortunately we decided together to go down the Scala road. See this Interview for more insight on the decision (not very technical and in german)
Here's the upcoming (it's Beta at the time of this writing) Play Store listing for the App.
We develop this app with Scala 2.11 for Android 4.0.3 and above.
Main MotivationScala is a beautiful language. I come from Java land, and it was a real eye opener to work with Scala and learn day by day more of the beauty of functional programming. So I definitely wanted to write as much Scala code and as less Java code as possible, even on Android.
But there's one really convincing feature in Scala that makes your life on Android so much easier and less painful: Futures instead of AsyncTask's Callback Handler approach.
With callback handler's you'll get soon in a spaghetti code situation. If you use Scala Future's you may easily combine them with their combinators, for-comprehensions or the new async/await macros. Just write some code with both concepts and you will see the difference.
For a more detailed view on the motivation, see my follow up post.
I'll now start with the basic building blocks of the App.
Build systemOne of the biggest questions when you start is: "Which build system should I use?" As I'm not a big fan of SBT I tried to look around and found one for my favourite build system gradle: gradle-android-scala-plugin. But unfortunately the author doesn't recommend it to use it in production yet.
So I tried out the Android SDK Plugin for SBT and it turned out to be very well. It is actively developed, the author is very responsive and helpful, and the Intellij integration via the SBT-Idea plugin is working well enough.
Scala and the Dexer limitCompiled Java code for android is not shipped as .class files but in a format called dex. The problem is that currently one dex file allows only 65k method entries, and there are some big java android apps out there that already hit this limit. (e.g. the facebook app).
So even if you have a normal sized app, if you write it in Scala the scala library itself will reach this limit. But every Android developer knows ProGuard: A tool which inspects java bytecode and removes unused code and optionally obfuscates it.
These tools are very well integrated in the Android SDK Plugin for SBT, where you also have the possibility to customize a Proguard cache to save a lot of time during your development build cycles.
REST clientAs a rest client we use the Spring Android REST Template from Spring Android. Not much to say here, it just works well. (In my Java days I was a big Spring fan.) We don't use the standard spring json parsing message converters. See next chapter.
Json ParsingFor my own (and first) Android app in Java I had used GSon for Json Parsing. It's very small and easy to use but unfortunately (and not surprisingly) it does not well support the Scala types we all love to use: Options, Lists etc.
So my next evaluation was to use Jackson together with the Jackson Scala Module. At Gutefrage.net we use it on the Scala server side, but it showed up that it is very cumbersome to use on Android. The main reason is that it heavily relies on reflection and if you look at how Proguard works, you'll get a feeling why this will cause trouble. You'll have to add several "-keep" rules to tell Proguard not to remove code that Jackson needs later on to build up your object graph from json, and a lot of more stuff. I would not recommend it.
So the final library in my journey was spray-json. It is a native Scala library and you define your json mapping as an external protocol (in Scala).
This has several advantages:
- No annotation and no reflection magic, all compile time, so no need to configure Proguard in any special way
Type-class based (de)serialization of custom objects (no reflection, no intrusion)
- Annotations (e.g. used in Jackson) allow one representation, external protocol allows multiple
- Define a protocol for classes w/o source
- Simple and lightweight (Jar Size compared to Jackson)
- Plugging in of fast low level parsers simple
Libraries for making Android less painfulWe use Scaloid, it has several nice features e.g.
- turning the usual android callback handlers (e.g. onClickListener) into a functional equivalent
- a Scala DSL for building and reusing layouts
- a lot of Rich* classes for the Android functionality and implicit parameters reducing a lot of boilerplate code
- and a lot more
Another UI DSL Library which might be worth to have a look at is Macroid.
The next upcoming post will talk about generalizing the error handling while talking to API servers.