Scala: A Better Java for Android

Mike Burns

Stop writing Java for your Android apps!

There are a slew of ways to build Android apps. The original Java way reigns supreme but some alternatives are C++, Mirah, Python, Titanium Appcelerator, Corona, and so on.

And there’s Scala.

Scala can be thought of as a better Java. To start with, you don’t need as many semicolons. But Scala gives you the power of modern abstractions. Traits, implicits, type-checked null, blocks–everything you really need to get some solid coding done.

(Briefly, the magic Android sauce is the scalaforandroid project.)

As an example of what Scala can do for your app, take this simple project: a button which, when pressed, shows a toast:

    package com.thoughtbot.helloscala

    import _root_.android.app.Activity
    import _root_.android.os.Bundle
    import _root_.android.widget.Toast
    import _root_.android.view.View
    import _root_.android.view.View.OnClickListener
    import _root_.android.widget.Button

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

        val button = findViewById(R.id.button).asInstanceOf[Button]
        button.setOnClickListener(new View.OnClickListener() {
          def onClick(v : View) {
            Toast.makeText(this, "You have clicked the button",
            Toast.LENGTH_LONG).show()
          }
        })
      }
    }

This is basically the Java version without semicolons. But we can spruce it up with a trait and an implicit:

    package com.thoughtbot.helloscala

    import _root_.android.app.Activity
    import _root_.android.view.View
    import _root_.android.view.View.OnClickListener

    trait FindView extends Activity {
      def findView [WidgetType] (id : Int) : WidgetType = {
        findViewById(id).asInstanceOf[WidgetType]
      }
    }

    class ViewWithOnClick(view : View) {
      def onClick(action : View => Any) = {
        view.setOnClickListener(new View.OnClickListener() {
          def onClick(v : View) { action(v) }
        })
      }
    }

    object FindView extends Activity {
      implicit def addOnClickToViews(view : View) =
        new ViewWithOnClick(view)
    }

This adds an onClick method to Views and a findView method for Activities. Life just got a little more functional:

    package com.thoughtbot.helloscala

    import _root_.android.app.Activity
    import _root_.android.os.Bundle
    import _root_.android.widget.Toast
    import _root_.android.view.View
    import _root_.android.widget.Button
    import FindView._

    class HelloActivity extends Activity with FindView {
      override def onCreate(savedInstanceState : Bundle) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)

         findView[Button](R.id.button).onClick { view : View =>
            Toast.makeText(this, "You have clicked the button", Toast.LENGTH_LONG).show()
        }
      }
    }

Take this concept as far as you need: a doInBackground method for functions, a withState-like function for PreferenceManager, a caching wrapper for URLs–the sky is the limit here.

So what’s stopping you from using Scala for your Android app?