BAM Weblog

Minimalist Android Scala Environment

Brian McKenna2010-12-28

I managed to get Scala working on Android after the SDK was first released. I also found a little problem with the Dalvik virtual machine in the process.

A year and a half went by and I've come back to try Scala on Android. There's now a few resources on the topic, even one from ScalaIDE. I haven't been completely satisfied with the solutions I've read so I came up with the following.

Instructions

Install ScalaIDE in Eclipse and create a new Android project.

Make sure there is a directory called libs and copy in scala-library.jar. Make a new directory called tools and copy in scala-compiler.jar.

Generate an Ant build.xml file:

$ ~/android-sdk-linux_86/tools/android update project --target 1 --path .

Define a pre-compile stage in build.xml and add a Scala task:

<target name="-pre-compile" depends="-resource-src">
    <taskdef resource="scala/tools/ant/antlib.xml"
             classpath="tools/scala-compiler.jar:libs/scala-library.jar" />

    <scalac force="changed" deprecation="on" destdir="${out.classes.absolute.dir}"
            bootclasspathref="android.target.classpath">
        <src path="${source.absolute.dir}" />
        <src path="${gen.absolute.dir}" />
        <src refid="project.libraries.src" />
        <classpath>
            <fileset dir="${jar.libs.absolute.dir}" includes="*.jar" />
        </classpath>
    </scalac>
</target>

Android doesn't work very well when converting a huge amount of Java bytecode to Dalvik bytecode. To get around this, we can use Proguard to remove all unused parts of the Scala library. Enable Proguard for debug releases by adding the following to build.xml:

<target name="-debug-obfuscation-check">
    <property name="proguard.enabled" value="true" />
    <path id="out.dex.jar.input.ref" />
</target>

Make the install target local to our build.xml instead of importing it. This will make it easier for Eclipse later on:

<target name="install" depends="debug">
    <install-helper />
</target>

Add the following line to default.properties:

proguard.config=proguard.cfg

The Scala library will cause warnings and make Proguard stop. Make it continue by adding the following to proguard.cfg:

-dontwarn

Remove the default run configuration from Eclipse and add a new external run configuration. The buildfile should be ${project_loc}/build.xml and the base directory should be ${project_loc}. Go to the "Targets" tab and tick the "install" target.

Delete the default Java source file and recreate it using Scala:

package org.brianmckenna.helloandroid

import android.app.Activity
import android.os.Bundle

class HelloAndroid extends Activity {
  override def onCreate(savedInstanceState: Bundle): Unit = {
    super.onCreate(savedInstanceState)
    setContentView(List(R.layout.main) head)
  }
}

After starting the emulator and running Ant, Scala should now run on Android!

Please enable JavaScript to view the comments powered by Disqus.