Scala on Android

The comprehensive documentation

  • Information reliability Sustainable Won't become outdated
  • Last edit Wed Jun 24 17:48:48 2015 +0200
  • Edit on GitHub

Parcelable

You are discouraged to use the Java serialization framework on the Android platform for performance reasons. Instead, Android comes with its own serialization tool: Parcelable. A Parcelable class requires you to implement the Parcelable interface and also to fulfill a certain contract as show below.

import android.os.Parcel;
import android.os.Parcelable;

public class User implements Parcelable
{
    private int age;

    private String name;

    // Getters and Setters [...]

    public User( int age, String name ) {
        this.age = age;
        this.name = name;
    }

    protected User( Parcel source ) {
        this( source.readInt(), source.readString() )
    }

    @Override
    public int describeContents() { return 0; }

    @Override
    public void writeToParcel( Parcel destination, int flags ) {
        destination.writeInt( age );
        destination.writeString( name );
    }

    // Implemented by contract, if this field is not around you will encounter runtime
    // exceptions
    public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
        public User createFromParcel( Parcel source ) { return new User( source ); }

        public User[] newArray( int size ) { return new User[size]; }
    };
}

A Parcelable class forces you to implement a lot of boilerplate code, but offers great performance as it does not rely on runtime reflection like the default Java serialization framework. But when it comes to Scala on Android there emerges another problem: the Parcelable contract requires a static class member. This is impossible in Scala because there is no support for statics.

Luckily, the Scala compiler checks for the Android Parcelable interface and treats it in a special way to support Android development. At the end of the day there is just another contract to implement that relies on the class' companion to overcome the lack of statics. Below is a valid Scala implementation of the previous example.

import android.os.{ Parcel, Parcelable }

case class User( age: Int, name: String ) extends Parcelable {
    protected this( source: Parcel ) = this( source.readInt(), source.readString() )

    override def describeContents() = 0

    override def writeToParcel( destination: Parcel, flags: Int ) {
        destination.writeInt( age )
        destination.writeString( name )
    }
}

object User
{
    // This is by contract, the CREATOR field must exist for every class that implements
    // the Parcelable interface.
    override val CREATOR = new Parcelable.Creator[User] {
        override def createFromParcel( source: Parcel ) = new User( source )

        override def newArray( size: Int ) = new Array[User]( size )
    }
}
  • Information reliability Moderate Might become outdated
  • Last edit Tue Jun 9 15:46:52 2015 +0200
  • Edit on GitHub

Alternatives

Scala comes with first class macro support (compile time reflection). This allows for code generation at compile time that may help to reduce boilerplate in use cases like this without sacrificing performance. To simplify Inter Process Communication (IPC) with the Parcelable contract, you could instead try one of the numerous JavaScript Object Notation libraries, or Scala Pickling, a project that aims to bring boilerplate-free serialization to Scala.

Further reading

Comments