Purpose of this document

This document wants to show a possible approach aimed at using SCXML on Google Android. That is why the focus lies rather on the steps necessary for successfully deploying the statemachine than the application itself.

Stopwatch

This usecase is based on the stopwatch example. If you should not be acquainted with the stopwatch usecase you would probably want to read this first. The modeling of the statemachine as well as the scxml markup will not be covered here.

Motivation

  • Demonstrate steps to run a Commons SCXML Statemachine on Android.
  • Demonstrate what dependencies are not covered by Android and how to cut those ties.

Android Background

Android is a mobile operating system that is developed and released by the Open Handset Alliance. First handsets are expected to enter the market by October '08. Android is based on Linux and runs a virtual machine called the Dalvik VM. The SDK provides tools for transferring java bytecode to dalvik compatible bytecode.

Android comes with a subset of J2SE packages but also provides own libraries and other third party libraries. Interesting is the use of apache harmony as the implementation of its J2SE modules.

Prerequisites for building the Android Application

  • an installation of Android SDK 1.0 r1
  • good to have: ADT Plugin for Eclipse installed
  • knowing about the folder structure of an Android project.
  • knowing about the Role of Activities in Android applications.
  • understanding UI Layouts created by using Androids xml layout scheme.
  • being aware of Services, Intents and ContentProviders is an advantage

Building the Android Application

The Stopwatch Logic

As already mentioned this usecase is based on the stopwatch example. It uses both the stopwatch.xml and the StopWatch.java.

The Stopwatch UI

Here is the UI definition for the stopwatch: stopwatch_display.xml. Place it into /res/layout/ from the root of your project. Note how id's are declared and referenced. Declared id's will be available through the automatically generated R.java.

The Stopwatch Activity

Here is the Activity class StopWatchActivity.java which is the entry point of the application. That is also where the instance of StopWatch resides. Note how UI Elements are being referenced by using the R.java class. See also how a handler is used to display changes to the StopWatch from another Thread.

Resources

Commonly used strings are declared inside a strings.xml in /res/values/. Once you put it there the R.java gets updated and you can reference the strings using that class.

If you wish to have a non standard icon you can replace /res/drawable/icon.png with this icon.png:

Manifest

Each Android application has a AndroidManifest.xml. It resides inside the root directory and is used to declare the overall structure of the application.

Handling unmet dependencies

The real challenge of running a commons.scxml statemachine on Android are it's dependencies. After adding all needed libraries to the build path build errors will still occur. The reason is that the dependencies are based on a standard J2SE. In contrast Android uses a subset of J2SE, meaning that several packages are missing. Dependencies to J2SE are shown in this UML Package Diagram. Reviewing available packages on Android results in the conclusion that java.beans, java.awt and javax.swing are missing on Android. The dependency between Commons Beanutils and java.beans is strong. For meeting this putting the java.beans module (Apache Harmony) on the build path is a possibility. That module in turn has a dependency to harmony.kernel that needs to be removed. The yellow color of some of the packages in the diagram marks the places where code changes happened. These modifications removed the dependence to not available yet disposable J2SE packages. For a better documentation take a look at the diff file.

Building the .apk

Building the application is a bit tricky as well. You will notice that ADT will break up with the following error: "Conversion to Dalvik format failed with error 1". You will also find a detailed message that explains that you have tried to build a core library which is not recommended. To do so anyway you can pass dx (the java bytecode - dalvik bytecode transformer) the --core-library option. Concluding that by core-library java.* packages where meant, and having in mind what is about to be added there is no reason for giving up. The problem in passing the --core-library option is that there is no such possibility from within ADT. That problem can be met by using the activityCreator tool (to be found inside the tools directory of the SDK). This tool will create an empty project for you. This is meant for developers who are not using eclipse. Alongside with the project structure the tool generates an ant build script. Putting that build.xml to the original eclipse project enables you to pass the --core-library option to dx when using Apache Ant.

    <target name="dex" depends="compile">
     <echo>Converting compiled files and external libraries into ${outdir}/${dex-file}...</echo>
      <apply executable="${dx}" failonerror="true" parallel="true">
      <arg value="--dex" />
      <arg value="--core-library" />
      <arg value="--output=${intermediate-dex-ospath}" />
      <arg path="${outdir-classes-ospath}" />
      <fileset dir="${external-libs}" includes="*.jar"/>
     </apply>
    </target>
   

Now its time to build and install the project on your emulator.

The result


(Figure 1: Begin in state "reset")


(Figure 2: Start puts the stopwatch in "running" state)


(Figure 3: Split causes the stopwatch to be "paused")


(Figure 4: The stopwatch in "stopped")