Anyway, on with the main event: a working setup for developing Android applications in Scala. I spent about 3-4 days total trying to get this setup working, using various different schemes such as the Treeshaker plugin for Eclipse, the Maven Android plugin and others. After hours and hours of fiddling, I finally found a solution that works: a custom SBT setup with the SBT Android plugin. The key is to avoid building the Android app in Eclipse itself, but to use SBT for the heavy lifting.
Eclipse seems to have some very non-deterministic behavior when building applications, especially Android applications. When you add Scala and Treeshaker into the mix, the whole thing falls apart. Furthermore, the build process is very opaque, so it's hard to figure out what is even going wrong, let alone to try to fix it. A build which was fine before might suddenly stop working, raising some exception or simply pegging the processor and making Eclipse totally unresponsive. There doesn't seem to be any pattern to the madness, so it's impossible to fix.
Anyway, as I mentioned, SBT with the Android plugin works beautifully for building apps, but as much as I love Emacs, it is easier to work with Scala in an environment that gives you clear and immediate feedback about type failures and requirements. On the downside, in order to do all of this wonderfulness along with the Android helpers, Eclipse expects a very specific directory layout, and will complain if it does not exist. SBT, by default, uses a completely wacky layout, with the Android manifest files (usually at the root of the project) in
src/main/. This means that the actual source code files are in
src/main/src/main/java/com/example/.... For a single project without references to other projects, this is unnecessarily complicated and destroys the tiny brain of Eclipse. So the solution is to change SBT's layout to something sane.
Note: I'm using SBT 0.7.x since the SBT Android plugin hasn't yet been ported to 0.10.x
First of all, you need to declare the plugins you will be using (for now just the SBT Android plugin) in
project/plugins/plugins.scala. The actual filename doesn't matter, as long as it is in the
plugins.scalalooks like this:
Standard fare for SBT plugins.
Next is the SBT project file. This is where the magic happens, though there isn't really that much magic to it. It simply changes some paths so that SBT looks in the correct place. Here's the file:
The keys are the five lines in the middle setting the path info. The
androidManifestPathassignment causes SBT to look for
AndroidManifest.xmlin the project root, as do
mainAssetsPath. Setting the scala and java source paths to
srcmeans that SBT will look in that folder instead of the redundantly redundant
src/main/srcdirectory. Finally, overriding
aaptwrite the generated resource files (
R.javaand friends) to the
genfolder, as the Android Eclipse plugin expects.
With the hard stuff out of the way, you "simply" need to configure Eclipse to use the appropriate builders and classpaths, included in the
.classpathfiles, respectively. Here they are:
Obviously, since the config files include the Scala libraries and builder, you'll need to install the Scala Eclipse IDE. With all of this in place, you should be able to issue a simple
sbt start-emulatorto build, Proguard, package, deploy and start your application.
Hopefully this post will save you from the pain I endured of trying to get Scala working on the one hand, and the thought of having to use Java on the other.