Tweaking the Android emulator

by Stephane Micheloud, June 2010

[Home]
[Back]

In this article we present a way to extend the boot class path of the Dalvik-VM with additional Java libraries. That possibility is particularly interesting when developing Android applications written in Scala since it solves the issue we described in the article "Shrinking the Scala library code".

Our solution is partly inspired from Brault's article "Les dessous d'Android", published in the September 2009 issue of the Linux Magazine. In particular Frédéric Brault describes how to modify the Android runtime environment so that it behaves more Unix-like. He also presents BusyBox, a comfortable shell toolbox available for various embedded devices and licensed under GPLv2.

Note: The Android emulator includes Toolbox, a light-weight shell toolbox (~75 KB), which provides 51 shell commands with basic functionality while BusyBox (~1 MB in size) provides a much richer set of commands (e.g. 323 commands in version 1.16.1).

Android smartphones also provide the BusyBox shell toolbox; for instance when clicking on the thumbnail on the right you can see a screen capture of an HTC Desire device.

BusyBox Thumbnail

Custom ramdisk.img

We want to create custom ramdisk images (one per available target) with pre-installed Scala libraries and to pass them as argument when launching the Android emulator (using the -ramdisk <file> option) .

We proceed as follows (the operations below are actually performed by the shell script "bin/createramdisks"):

The generated ramdisk.img files are kept in the user directory $ANDROID_SDK_HOME/.android/avd/ and can thus be shared between all Android projects; here is an example of our Android user environment:

$ ls $ANDROID_SDK_HOME/.android/avd/
API_7.avd                API_8_Google.avd-custom
API_7.avd-custom         API_8_Google.ini
API_7_Google.avd         API_8.ini
API_7_Google.avd-custom  API_9.avd
API_7_Google.ini         API_9.avd-custom
API_7.ini                API_9_Google.avd
API_8.avd                API_9_Google.avd-custom
API_8.avd-custom         API_9_Google.ini
API_8_Google.avd         API_9.ini
$ cat $ANDROID_SDK_HOME/.android/avd/API_8.avd/config.ini
hw.lcd.density=160
sdcard.size=128M
skin.name=HVGA
skin.path=platforms/android-8/skins/HVGA
image.sysdir.1=platforms/android-8/images/
$ ls -s $ANDROID_SDK_HOME/.android/avd/API_8.avd-custom
total 777
777 ramdisk.img

Note: For convenience we provide the following four archives for Android developers working on the Windows platform (a Unix environment is required to generate the ramdisk images).

The Java system libraries are located in the following two directories (which are respectively read-only and read-write directories); the jar files contained in directory /data/framework/ are installed once using the command push-jars defined in the the Ant build script build.xml:

$ adb shell /bin/ls -s /system/framework /data/framework
/system/framework:
   9 am.jar                   2647 framework.jar
  84 android.policy.jar          3 ime.jar
  74 android.test.runner.jar     2 input.jar
   6 bmgr.jar                   26 javax.obex.jar
2105 core.jar                   32 monkey.jar
 229 ext.jar                    11 pm.jar
4668 framework-res.apk         607 services.jar
   9 framework-tests.jar         4 svc.jar

/data/framework:
 201 scala-actors.jar         1135 scala-library.jar
 735 scala-collection.jar      312 scala-mutable.jar
 380 scala-immutable.jar

We check that the value of the environment variable BOOTCLASSPATH is correctly extended with the pre-installed Scala libraries.

$ adb shell echo '$BOOTCLASSPATH'
BOOTCLASSPATH=/system/framework/core.jar:/system/framework/ext.jar:\
    /system/framework/framework.jar:/system/framework/android.policy.jar:\
    /system/framework/services.jar:/data/framework/scala-library.jar:\
    /data/framework/scala-collection.jar:/data/framework/scala-immutable.jar:\
    /data/framework/scala-mutable.jar:/data/framework/scala-actors.jar

And we have direct access to the BusyBox commands (e.g. "/bin/ls") thanks to the modified PATH variable:

$ adb shell echo '$PATH'
/bin:/sbin:/system/sbin:/system/bin:/system/xbin

Custom shell scripts

Finally we briefly present a small shell script excerpt to demonstrate how our custom ramdisk.img files are easily selected before launching the Android emulator with some user configured AVD:

## .. (skipped)

AVD="API_9" # some default AVD
AVD_HOME=$ANDROID_SDK_HOME/.android/avd
if [ ! -f "$AVD_HOME/$AVD.ini" ] ; then
    echo "Error: Device '$AVD' is unknown."
    echo "  We cannot execute $EMULATOR."
    exit 1
fi
if [ -z "$ANDROID_EMULATOR_OPTS" ] ; then
    EMULATOR_OPTS="-no-boot-anim -no-skin"
    if [ -f "$AVD_HOME/$AVD.avd-custom/ramdisk.img" ] ; then
        RAMDISK=$AVD_HOME/$AVD.avd-custom/ramdisk.img
        EMULATOR_OPTS="$EMULATOR_OPTS -ramdisk $RAMDISK"
    fi
else
    EMULATOR_OPTS="$ANDROID_EMULATOR_OPTS"
fi
exec $EMULATOR $EMULATOR_OPTS -avd $AVD

For convenience the .zip archive android-sdk.zip includes the two shell scripts bin/emulator and bin/emulator-maps which automatically check for the presence of custom ramdisk.img files (the scripts are also present in the .zip archive unlocking-android.zip).

That's it ! We can now switch back to our Scala code writing.

Update (December 10, 2010): Linux users should first check the version of the GLIBC library installed on their system (eg. version 2.7 on Ubuntu 8.04 aka "Hardy") as the Android 2.3 emulator requires version 2.11 (or newer) of the GLIBC library (installation proceeds silently :-( You are now warned!):

/opt/android-sdk-linux_86/tools$./emulator
./emulator: /lib/tls/i686/cmov/libc.so.6:
    version `GLIBC_2.8' not found (required by ./emulator)
./emulator: /lib/tls/i686/cmov/libc.so.6:
    version `GLIBC_2.11' not found (required by ./emulator)

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