Writing a Scala API for Android

by Stephane Micheloud, July 2010

[Home]
[Back]

Today we look in more detail at the scala-android.jar library we mentioned at the end of our article "Translating Java code to Scala". At this stage of its development that library provides basic functionality but should support more advanced features in a next future as does the scala-swing.jar library (part of the standard Scala software distribution).

A closer look at scala-android.jar

The scala-android.jar library exists in two slightly different versions: the android-8 version is actually a superset of android-7 version and provides a few API additions (mostly constants) introduced in release 2.2 of the Android platform.

android-examples> tree scala-framework/android/src/
scala-framework/android/src/
|-- android-7
|   `-- scala
|       `-- android
|           |-- app
|           |   |-- Activity$.java
|           |   `-- Activity.scala
|           |-- maps
|           |   |-- Overlay$.java
|           |   `-- Overlay.scala
|           |-- package.scala
|           `-- provider
|               |-- Contacts.java
|               `-- ContactsContract.java
`-- android-8
    `-- <same hierarchy as in "android-7">

12 directories, 14 files

Example 1

Wrapper objects such as scala.android.provider.ContactsContract give direct access to inherited Java constants defined in Java static inner interfaces. For instance, in the following Scala code we access the constant Phone.TYPE directly as in Java although it is actually defined in the static inner interface CommonColumns (see the blog entry "Scala on Android Gotcha: HelloGridView Error" for more details).

// ContactAdder.java
import android.provider.ContactsContract.CommonDataKinds.Phone;
//..
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
        .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
        .withValue(ContactsContract.Data.MIMETYPE,
                   Phone.CONTENT_ITEM_TYPE)
        .withValue(Phone.NUMBER, phone)
        .withValue(Phone.TYPE, phoneType)
        .build());
// ContactAdder.scala
import scala.android.provider.ContactsContract.CommonDataKinds.Phone
//..
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
        .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
        .withValue(ContactsContract.Data.MIMETYPE,
                   Phone.CONTENT_ITEM_TYPE)
        .withValue(Phone.NUMBER, phone)
        .withValue(Phone.TYPE, phoneType)
        .build())

Example 2

Boilerplate code can be reduced using Scala implicit conversions. Thus passing event handlers to methods setOnItemSelectedListener and setOnClickListener can be expressed in a more concise way by the Scala programmer (see the StackOverflow blog entry "What is in scala-android.jar ?" for an example).

// ContactAdder.java
import android.app.Activity;
//..
mAccountSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
    public void onItemSelected(AdapterView<?> parent, View view,
                               int position, long i) {
        updateAccountSelection();
    }
    public void onNothingSelected(AdapterView<?> parent) {
        // We don't need to worry about nothing being selected,
        // since Spinners don't allow this.
    }
});
mContactSaveButton.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        onSaveButtonClicked();
    }
});
private void onSaveButtonClicked() { /* .. */ }
// ContactAdder.scala
import scala.android.app.Activity
//..
mAccountSpinner setOnItemSelectedListener {
  updateAccountSelection()
}
mContactSaveButton setOnClickListener {
  onSaveButtonClicked()
}

Note: In case the Scala programmer needs to provide some code for the onNothingSelected event he can simply write:

mAccountSpinner setOnItemSelectedListener {
  updateAccountSelection()
} orNothing {
  // onNothingSelected code
}

Example 3

to be done

About the Author

Stephane's Picture
Stéphane Micheloud is a senior software engineer. He holds a Ph.D in computer science from EPFL and a M.Sc in computer science from ETHZ. At EPFL he worked on distributed programming and advanced compiler techniques and participated for over six years to the Scala project. Previously he was professor in computer science at HES-SO // Valais in Sierre, Switzerland.
[Top]

Other Articles