Tiliman’s Weblog

February 10, 2010

Android Development with Scala

Filed under: Android, Mobile Software Development — Tags: , , , , , — tiliman @ 4:33 pm

I learned a few weeks back about Scala programming language. I never liked Java and thought to try Scala as I would learn functional language and be able to still use JVMs.
I also wanted to learn Android development as I have done previously Windows Mobile, Symbian and iPhone development. Using Scala with Android was my idea to hit 2 birds with one stone.

Android Decelopment using Eclipse and Scala language

Android Decelopment using Eclipse and Scala language

All the information that I could find about using Scala with Android was for Android 1.6/1.7 but not with Android 2.0.1. Today finally I got Scala-Android development working for me. I am using Eclipse for development on OSX.

The steps involved are documented in detail here which can be followed till Step 4 as after that I will explain the trick to use Scala . If you are an advanced programmer then you should be able to follow my brief guide below.

Increasing memory of Eclipse

Edit eclipse.ini file which can be found in OSX at /Applications/Eclipse/Eclipse.app/Contents/MacOS/eclipse.ini
If you have not made changes to an app contents before in OSX then for your information right-click Show Package Contents displays all the internal directories in .app bundle.
Make sure that these parameters are there in config file as below


256m
-vmargs
-Xms256m
-Xmx1024m
-XX:PermSize=64m

Goto android sdk tools directory at <ANDORID_SDK>/platforms/android-2.0.1/tools/dx.sh and edit it and make sure this param is there


defaultMx="-Xmx512M"

It can be different on windows as windows uses batch file. You can find it as -Xmx<NNN>M where NNN is the memory size.

Note: mine was setup as 1024M so I kept it like that. 512M should work fine as well.

Install Android 2.x.x SDK

Download and install Android SDK and Tools from this link http://developer.android.com/sdk/eclipse-adt.html
I had to use HTTP instead of HTTPS for installing ADT plugin on Eclipse.

Install Scala

Download and install Scala plugin for Eclipse
You can put this URL directly in Install New Software feature of Eclipse
Scala – http://www.scala-lang.org/scala-eclipse-plugin
More details can be found at http://www.scala-lang.org/node/94

Download and install full Scala installer as well to get more control on Scala as well as get sbaz support.
http://www.scala-lang.org/downloads/distrib/files/scala-2.7.6.final-installer.jar or find whatever is the latest version at the time of reading.

Install scala-android library for development

Download and install scala-android.jar (library)


sbaz install scala-android

You can compile it yourself by visiting this link http://robey.lag.net/2009/01/19/scala-on-android.html

Create an Android project

Add Scala Nature by right clicking on project and then Scala->Add Scala Nature

Fix Project settings to use Scala

Scala Eclipse Settings

Scala Eclipse Settings

Goto Properties->Builders tab and make Scala Builder as 2nd last item in list.

Goto Java Build Path->Libraries and Remove Scala Library Version 2.x
In same Java Build Path->Libraries, Add External Jar and locate scala-android.jar in lib directory of Scala SDK.

Extending Scala class from Java

I always had issue compiling Android app written in Scala with class not being found as per manifest file. The issue was somewhere between Java expecting .java file as starting point and not being able to find it. So, I found a solution to leave original .java file as entry point and make a new file for Scala. Now the Java startup/main class extends Scala class which allows me to write rest of application in Scala.
My project was called ScalaTest and the ScalaTest.java was boilerplate code generated by android new project wizard.
The file looks like this after changes made for Scala


package android.ScalaTest;

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

public class ScalaTest extends MainScala {}

The MainScala.scala looks like this


class MainScala extends Activity {
    override def onCreate(savedInstanceState: Bundle) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)
    }
}




First Scala Application

First Scala Application

Thats it. Scala can be used to do rest of Android Development as well as Debugging. Now I am off to learn Scala with Android.

About these ads

18 Comments »

  1. Your fix for getting around android SDK complaining about the android.app.Activity is not extended does not work for me.

    Instead now it complains that “MainScala cannot be resolved to a type” in the ScalaTest.java file

    Comment by Brian — February 25, 2010 @ 2:00 am

    • There must be something missing.
      The error means that java can’t find MainScala class. This probably is because MainScala is not in the path. Make sure it is in correct path and all scala related settings are correct. Try creating a new project and follow steps carefully. If still it gives you error, send me the new project you created and I will check it out.

      Comment by tiliman — February 25, 2010 @ 5:46 am

      • Thanks for the reply. I don’t know if you included this in your instructions..but I noticed the the main scala website (http://www.scala-lang.org/node/160) mentions that one needs to add the bin directory to the java build path, I did that and the problem finally went away. And I finally succeeded and was able the get my hello world app written in scala to run on the emulator.

        By the way is there really no way to avoid the work around where you have a java class extend the scala class?

        Comment by Brian — February 25, 2010 @ 5:51 am

      • Actually I didn’t have to do it at all and for me project worked as it is.
        Thanks for the tip. It should help others who endup with same problem.

        Comment by tiliman — February 25, 2010 @ 5:59 am

  2. As a programmers what do u think android OS compare to RIM blackberry

    Comment by nicebee — April 20, 2010 @ 3:13 pm

    • I have never done any blackberry development. I only once tried to look for a way to intercept every SMS and I couldn’t find a way to do it.
      So, I would rather not comment on which OS is better.
      On the other hand, I got an idea from your post to see if Scala can be used for BlackBerry development.

      Comment by tiliman — April 20, 2010 @ 3:55 pm

      • I am very interested in this question too. My investigation has not revealed a way to use scale on blackberry, i think it can not be done, because the blackberry is based on J2ME

        Comment by Brian — April 20, 2010 @ 9:16 pm

      • Did you ever find out? I was wondering the same thing (regarding Blackberry dev with Scala).

        Comment by Felipe D. — September 11, 2010 @ 4:23 pm

      • No I never got time to try that out.

        Comment by tiliman — September 11, 2010 @ 5:18 pm

      • Nops. Never tried it.

        Comment by tiliman — February 18, 2011 @ 9:41 pm

      • I have never tried that. I am not sure if that is possible at all from handset.

        Comment by tiliman — February 18, 2011 @ 9:43 pm

  3. Note to self.
    Sometimes the Java class that extends Scala class complaints about hierarchy inconsistency. This is resolved by putting bin directory of project as top most item in Order And export in Java Built Path

    Comment by tiliman — June 20, 2010 @ 8:41 pm

  4. Hi

    I do have the following issue on MacOSX with eclipse helios , scala-2.9.0-final. Further more i obtained scala-android(2.7.0-final). In this certain case i am using android-2.2 but could easily reproduce this also using android-3.0 or whatever . In eclipse everything is working fiine , code completion and the generation of R.class and the compiling of the scala class mentioned below.
    The generated apk in the bin folder is called XmlScalaAndroid2.apk . The dex viewer which is part of the android tools produces the following output.

    Processing ‘/Users/mschlech/workspace/XmlScalaAndroid2/bin/classes.dex’…
    Opened ‘/Users/mschlech/workspace/XmlScalaAndroid2/bin/classes.dex’, DEX version ’035′
    Class #0 -
    Class descriptor : ‘Lcom/entscheidungsbaum/scala/android/xml/R$attr;’
    Access flags : 0×0011 (PUBLIC FINAL)
    Superclass : ‘Ljava/lang/Object;’
    Interfaces -
    Static fields -
    Instance fields -
    Direct methods -
    #0 : (in Lcom/entscheidungsbaum/scala/android/xml/R$attr;)
    name : ”
    type : ‘()V’
    access : 0×10001 (PUBLIC CONSTRUCTOR)
    code -
    registers : 1
    ins : 1
    outs : 1
    insns size : 4 16-bit code units
    catches : (none)
    positions :
    0×0000 line=11
    locals :
    0×0000 – 0×0004 reg=0 this Lcom/entscheidungsbaum/scala/android/xml/R$attr;
    Virtual methods -
    source_file_idx : 11 (R.java)

    Class #1 -
    Class descriptor : ‘Lcom/entscheidungsbaum/scala/android/xml/R$drawable;’
    Access flags : 0×0011 (PUBLIC FINAL)
    Superclass : ‘Ljava/lang/Object;’
    Interfaces -
    Static fields -
    #0 : (in Lcom/entscheidungsbaum/scala/android/xml/R$drawable;)
    name : ‘icon’
    type : ‘I’
    access : 0×0019 (PUBLIC STATIC FINAL)
    Instance fields -
    Direct methods -
    #0 : (in Lcom/entscheidungsbaum/scala/android/xml/R$drawable;)
    name : ”
    type : ‘()V’
    access : 0×10001 (PUBLIC CONSTRUCTOR)
    code -
    registers : 1
    ins : 1
    outs : 1
    insns size : 4 16-bit code units
    catches : (none)
    positions :
    0×0000 line=13
    locals :
    0×0000 – 0×0004 reg=0 this Lcom/entscheidungsbaum/scala/android/xml/R$drawable;
    Virtual methods -
    source_file_idx : 11 (R.java)

    Class #2 -
    Class descriptor : ‘Lcom/entscheidungsbaum/scala/android/xml/R$layout;’
    Access flags : 0×0011 (PUBLIC FINAL)
    Superclass : ‘Ljava/lang/Object;’
    Interfaces -
    Static fields -
    #0 : (in Lcom/entscheidungsbaum/scala/android/xml/R$layout;)
    name : ‘main’
    type : ‘I’
    access : 0×0019 (PUBLIC STATIC FINAL)
    Instance fields -
    Direct methods -
    #0 : (in Lcom/entscheidungsbaum/scala/android/xml/R$layout;)
    name : ”
    type : ‘()V’
    access : 0×10001 (PUBLIC CONSTRUCTOR)
    code -
    registers : 1
    ins : 1
    outs : 1
    insns size : 4 16-bit code units
    catches : (none)
    positions :
    0×0000 line=16
    locals :
    0×0000 – 0×0004 reg=0 this Lcom/entscheidungsbaum/scala/android/xml/R$layout;
    Virtual methods -
    source_file_idx : 11 (R.java)

    Class #3 -
    Class descriptor : ‘Lcom/entscheidungsbaum/scala/android/xml/R$string;’
    Access flags : 0×0011 (PUBLIC FINAL)
    Superclass : ‘Ljava/lang/Object;’
    Interfaces -
    Static fields -
    #0 : (in Lcom/entscheidungsbaum/scala/android/xml/R$string;)
    name : ‘app_name’
    type : ‘I’
    access : 0×0019 (PUBLIC STATIC FINAL)
    #1 : (in Lcom/entscheidungsbaum/scala/android/xml/R$string;)
    name : ‘hello’
    type : ‘I’
    access : 0×0019 (PUBLIC STATIC FINAL)
    Instance fields -
    Direct methods -
    #0 : (in Lcom/entscheidungsbaum/scala/android/xml/R$string;)
    name : ”
    type : ‘()V’
    access : 0×10001 (PUBLIC CONSTRUCTOR)
    code -
    registers : 1
    ins : 1
    outs : 1
    insns size : 4 16-bit code units
    catches : (none)
    positions :
    0×0000 line=19
    locals :
    0×0000 – 0×0004 reg=0 this Lcom/entscheidungsbaum/scala/android/xml/R$string;
    Virtual methods -
    source_file_idx : 11 (R.java)

    Class #4 -
    Class descriptor : ‘Lcom/entscheidungsbaum/scala/android/xml/R;’
    Access flags : 0×0011 (PUBLIC FINAL)
    Superclass : ‘Ljava/lang/Object;’
    Interfaces -
    Static fields -
    Instance fields -
    Direct methods -
    #0 : (in Lcom/entscheidungsbaum/scala/android/xml/R;)
    name : ”
    type : ‘()V’
    access : 0×10001 (PUBLIC CONSTRUCTOR)
    code -
    registers : 1
    ins : 1
    outs : 1
    insns size : 4 16-bit code units
    catches : (none)
    positions :
    0×0000 line=10
    locals :
    0×0000 – 0×0004 reg=0 this Lcom/entscheidungsbaum/scala/android/xml/R;
    Virtual methods -
    source_file_idx : 11 (R.java)

    Suprisingly the class ( the only one in the project ) can not be found. In the middle of the stacktrace it is searching within dalvik.system.PathClassLoader[/data/app/com.entscheidungsbaum.scala.android.xml-1.apk which is a little bit strange because this is not the name of my apk .

    Here we go with the stacktrace:
    05-24 22:15:44.895: WARN/dalvikvm(365): Link of class
    > 'Lcom/entscheidungsbaum/scala/android/xml/XmlLauncherScala;' failed
    > 05-24 22:15:44.915: DEBUG/AndroidRuntime(365): Shutting down VM
    > 05-24 22:15:44.915: WARN/dalvikvm(365): threadid=1: thread exiting
    > with uncaught exception (group=0x40015560)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): FATAL EXCEPTION: main
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365):
    > java.lang.RuntimeException: Unable to instantiate activity
    > ComponentInfo{com.entscheidungsbaum.scala.android.xml/com.entscheidungsbaum.scala.android.xml.XmlLauncherScala}: java.lang.ClassNotFoundException: com.entscheidungsbaum.scala.android.xml.XmlLauncherScala in loader dalvik.system.PathClassLoader[/data/app/com.entscheidungsbaum.scala.android.xml-1.apk]
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1544)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1638)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > android.app.ActivityThread.access$1500(ActivityThread.java:117)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > android.app.ActivityThread$H.handleMessage(ActivityThread.java:928)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > android.os.Handler.dispatchMessage(Handler.java:99)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > android.os.Looper.loop(Looper.java:123)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > android.app.ActivityThread.main(ActivityThread.java:3647)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > java.lang.reflect.Method.invokeNative(Native Method)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > java.lang.reflect.Method.invoke(Method.java:507)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > com.android.internal.os.ZygoteInit
    > $MethodAndArgsCaller.run(ZygoteInit.java:839)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > dalvik.system.NativeStart.main(Native Method)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): Caused by:
    > java.lang.ClassNotFoundException:
    > com.entscheidungsbaum.scala.android.xml.XmlLauncherScala in loader
    > dalvik.system.PathClassLoader[/data/app/com.entscheidungsbaum.scala.android.xml-1.apk]
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > dalvik.system.PathClassLoader.findClass(PathClassLoader.java:240)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > java.lang.ClassLoader.loadClass(ClassLoader.java:551)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > java.lang.ClassLoader.loadClass(ClassLoader.java:511)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > android.app.Instrumentation.newActivity(Instrumentation.java:1021)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): at
    > android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1536)
    > 05-24 22:15:44.955: ERROR/AndroidRuntime(365): … 11 more
    > 05-24 22:15:44.995: WARN/ActivityManager(62): Force finishing
    > activity com.entscheidungsbaum.scala.android.xml/.XmlLauncherScala

    It is a lot of information, i know , but may be it is trivial to solve . To be honest i have no clue.

    Would apreciate helping hands,

    best to all

    Marcus

    Comment by Marcus — May 25, 2011 @ 9:05 am

    • Hi

      Using scala-2.9.0-final with scala-android(2.7.0-final) is wrong. I tried myself a few weeks ago and I couldn’t succeed in compiling. Try using scala-2.7 and that should work fine.

      I will update with 2.9.0 when I try again and hopefully succeed. Just too busy in other work these days.

      Comment by tiliman — May 27, 2011 @ 8:16 pm

      • Hi tiliman,

        Thanks for that hint. I figure out that i installed to many packages in the android installation. I am using currently the maven android plugin in it worked out after i reinstalled android and got a limited subset of packages.
        I also tweaked from a former project the proguard environment what was probably the root cause of the problem mentioned above.

        Thanks for the hint, because i will also try this whole thing without maven.
        I can update you if you are interested in my findings , let me know.

        Best and thanks a lot.
        Marcus

        Comment by Marcus — May 29, 2011 @ 8:01 pm

      • Hi

        Awesome that you got it working. I will try the maven method as well.
        I will be waiting for your update.

        Comment by tiliman — May 30, 2011 @ 8:02 am

  5. Excellent tutorial, very useful, nice, thanks

    Comment by House of Androids — May 27, 2011 @ 7:26 pm

  6. FYI, I write a plugin for Scala + Android development that takes a slightly different approach. It’s available at https://github.com/banshee/AndroidProguardScala, or just point Eclipse to this update location: https://androidproguardscala.s3.amazonaws.com/UpdateSiteForAndroidProguardScala.

    Comment by phonebanshee (@phonebanshee) — June 15, 2012 @ 3:41 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Silver is the New Black Theme Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 200 other followers

%d bloggers like this: