Skip to content

hyysguyang/android-sdk-scala

Repository files navigation

===============================================================================
                                ANDROID EXAMPLES
                         Code examples written in Scala
                        and adapted from the Android SDK
===============================================================================

This document describes code examples written in Scala and adapted from the
Java examples available together with the Android SDK from Google Inc.
(http://developer.android.com/sdk/). Both the Java source code and the Scala
source code are licensed under the Apache License, Version 2.0.

For information about Scala as a language, you can visit the web site
http://www.scala-lang.org/

In the following we describe the build and installation of our Android
applications written in Scala (and in Java) using the Apache Ant build tool.
Note that the build instructions below apply to both the Unix and Windows
environments.

All Android examples have been run successfully on the virtual Android device
"2.2_128M_HVGA" configured as follows: 2.2 target, 128M SD card and HVGA skin
(for more details see the documentation page
$ANDROID_SDK_ROOT/docs/guide/developing/tools/avd.html).

NB. The file INSTALL.txt gives VERY USEFUL informations about the small
development framework (directories "bin/" and "configs/") included in this
software distribution; in particular it permits to greatly reduce the build
time of Android applications written in Scala.


Software Requirements
---------------------

In order to build/run our Android examples we need to install the following
free software distributions (tested versions and download sites are given in
parenthesis) :

1) Sun Java SDK 1.6 or newer (1.6.0_22   , www.sun.com/java/jdk/)
2) Scala SDK 2.7.5 or newer  (2.8.1.final, www.scala-lang.org/downloads/)
3) Android SDK 1.5 or newer  (2.2        , developer.android.com/sdk/)
4) Apache Ant 1.7.0 or newer (1.8.1      , ant.apache.org/)
5) ProGuard 4.4 or newer     (4.5.1      , www.proguard.com/)

NB. In this document we rely on Ant tasks featured by the Scala SDK, the
Android SDK and the ProGuard shrinker and obfuscator tool (we will say more
about ProGuard when we look at the modified Ant build script).


Project Structure
-----------------

The project structure of an Android application follows the directory layout
prescribed by the Android system (for more details see the documentation page
$ANDROID_SDK_ROOT/docs/guide/developing/other-ide.html#CreatingAProject).

In particular:

* The "AndroidManifest.xml" file contains essential information the Android
  system needs to run the application's code (for more details see the docu-
  mentation page $ANDROID_SDK_ROOT/docs/guide/topics/manifest/manifest-intro.html)

* The "build.properties" file defines customizable Ant properties for the
  Android build system; in our case we need to define at least the following
  properties (please adapt the respective values to your own environment):

  Unix:                                Windows:
     sdk.dir=/opt/android-sdk-linux_86    sdk.dir=c:/Progra~1/android-sdk-windows
     scala.dir=/opt/scala                 scala.dir=c:/Progra~1/scala
     proguard.dir=/opt/proguard           proguard.dir=c:/Progra~1/ProGuard

* The "default.properties" file defines the default API level of an Android
  (for more details see the documentation page
  $ANDROID_SDK_ROOT/docs/guide/appendix/api-levels.html).

* The "build.xml" Ant build script defines targets such as "clean", "install"
  and "uninstall" and has been slightly modified to handle also Scala source
  files. Concretely, we override the default behavior of the "-dex" target and
  modify its dependency list by adding the imported target "scala-compile" :

    <import file="build-scala.xml"/>

    <!-- Converts this project's .class files into .dex files -->
    <target name="-dex" depends="compile, scala-compile, scala-shrink">
        <scala-dex-helper />
    </target>

* The "build-scala.xml" Ant build script defines the targets "scala-compile"
  and "scala-shrink" where respectively the "<scalac>" Ant task generates
  Java bytecode from the Scala source files and the "<proguard>" task creates a
  shrinked version of the Scala standard library by removing the unreferenced
  code (see next section for more details). Those two tasks are featured by
  the Scala and ProGuard software distributions respectively.


Project Build
-------------

We assume here the Android emulator is up and running; if not we start it
using the shell command (let us assume the existence of the "2.2_128M_HVGA"
virtual device) :

   android-sdk> emulator -no-boot-anim -no-jni -avd 2.2_128M_HVGA &

Then we move for instance to the "Snake" project directory and execute one of
the following Ant targets :

   android-sdk> cd Snake
   Snake> ant clean
   Snake> ant scala-compile
   Snake> ant debug
   Snake> ant install
   (now let us play with our application on the emulator !)
   Snake> ant uninstall


===============================================================================


Note about ProGuard
-------------------

The main issue when building an Android application written in Scala is
related to the code integration of the Scala standard library into the
generated Android bytecode. Concretely, we have two choices :

1) We bundle (or better to say -- see the note below --, we try to bundle)
   the full Scala library code (an external library) together with our Android
   application as prescribed by the Android system (only system libraries can
   exist outside an application package).
   In Scala 2.8 the "scala-library.jar" library file has a size of about 5659K;
   it means that even the simplest Android application written in Scala would
   have a respectable foot print of at least 6M in size !

   NB. At this date (May 2010) we could not generate Android bytecode for the
   Scala standard library using the dx tool of the Android SDK. Thus, the
   execution of the following shell command fails with the error message
   "trouble writing output: format == null" :

   /tmp> dx -JXmx1024M -JXms1024M -JXss4M --no-optimize --debug --dex
         --output=/tmp/scala-library.jar /opt/scala/lib/scala-library.jar

2) We find a (possibly efficient) way to shrink the size of the Scala standard
   library by removing the library code not referenced by our Android
   application. Our solution relies on ProGuard, a free Ant-aware obfuscator
   tool written by Eric Lafortune; the ProGuard shrinker is fast and generates
   much smaller Java bytecode archives.

   Application     <myapp>.jar   Scala library classes    classes.dex
   (in Scala)                    (orig. 4151 classes)  (Android bytecode)
   -----------------------------------------------------------------------
   ApiDemos          1169K           409 classes             872K
   ContactManager     362K           362 classes             286K
   CubeLiveWallpaper  351K           353 classes             279K 
   FileBrowser        438K           433 classes             346K
   GestureBuilder      44K           403 classes             337K
   HelloActivity        3K             0 classes               2K
   Home               385K           365 classes             314K
   JetBoy             380K           369 classes             311K
   LunarLander        431K           427 classes             351K
   NotePad            356K           356 classes             282K
   PhoneDialer        326K           349 classes             256K
   SearchableDict     380K           380 classes             301K
   Snake              447K           428 classes             353K

   We now compare the build times and sizes of our Android applications
   (written in Scala) with the orginal examples (written in Java) from the
   Android distribution :

   Application        classes.dex   <app>-debug.apk(1)  build time(2)
                    (Scala / Java)   (Scala / Java)    (Scala / Java)
   ------------------------------------------------------------------
   ApiDemos           872K / 468K     2688K / 2174K     1m18s / 18s
   ContactManager     286K /  17K      127K /   25K       37s /  5s
   CubeLiveWallpaper  297K /  15K      120K /   19K       38s /  5s
   GestureBuilder     337K /  20K      144K /   28K       40s /  5s
   Home               314K /  32K      359K /  247K       40s /  6s
   JetBoy             311K /  24K     1647K / 1530K       47s / 13s
   LunarLander        351K /  18K      250K /  120K       39s /  5s
   NotePad            282K /  21K      132K /   48K       38s /  5s
   SearchableDict     301K /  15K      153K /   44K       45s /  4s
   Snake              353K /  14K      147K /   18K       46s /  4s

   (1) Sizes of application packages include bytecode and resources.
   (2) Elapsed times for Scala builds include ProGuard processing time.

   NB. The above results were measured with ProGuard 4.5.1 on a 2.0 GHz
   Pentium M with 2 GB of memory, using Sun JDK 1.6.0_21 and Scala 2.8.0.final
   on Ubuntu 8.04 Linux.


Have fun!
The Scala Team