Most of the interesting work in software development today occurs at one of the two extremes: huge cloud servers and tiny mobile devices. These domains solve significantly different problems, and, correspondingly, have different tool support. Server development often uses scripting languages to tie together different components and accomplish sophisticated automated tasks, while mobile development focuses on the particular capabilities and needs of a particular device and user.
However, these two extremes share a common language: Java™. Whether Android or the Spring framework, many of the most popular technologies today have adopted a language that's widely understood and supported around the world. This common language can lead to some surprising interactions between areas that you tend to think of as distinct. Java programming opens the door for many cross-platform options, such as easily porting server code to an Android device or tying into native platform abilities from existing components.
This article explores Ruboto, a project that bridges the gap between scripting languages and Android. You will learn about Ruby and Android, how they can come together in the Dalvik virtual machine, how to build and deploy your own scripts, and how this technology has potential for increasing programmer productivity and application flexibility.
Many scripting languages compete for programmers' affections, but Ruby currently holds a powerful position. Most famously, it supports the Rails web framework, but many developers also admire Ruby for its combination of terseness and elegance. An object-oriented scripting language with many modern features like duck typing and metaprogramming, Ruby is robust enough to support complex architectures and simple enough to perform ad hoc tasks.
Ruby comes in several flavors, including the popular JRuby. JRuby is a full Ruby interpreter that is written in the Java language and can run in a Java Virtual Machine (JVM). Unlike the official Ruby, JRuby lets you call Ruby scripts from within Java code, as well as call Java APIs from within your Ruby scripts.
Android was developed by the Open Handset Alliance, but it is most often thought of as a Google project. Today, Android powers about one quarter of all new smartphones, and its share of the market continues to rise.
Internally, Android runs on a modified Linux kernel. Most applications run in the Dalvik virtual machine (VM), a custom VM that Google designed from the ground up for optimal performance on mobile devices. You can learn more about Dalvik in Resources.
One point many new Android developers miss is that the Java source code they write does not run as Java bytecode. Instead, the Android toolkit converts Java bytecode into Dalvik bytecode. These converted files, which have the .dex extension, are packaged in the application that you deploy to the device. By the time the device runs your program, there's no Java bytecode left.
Charles Nutter, a member of the JRuby team, had an epiphany: because the Android toolchain could convert compiled Java code to Dalvik files, and because JRuby had a Ruby interpreter in compiled Java bytecode, then he should be able to run Ruby on Android. Within an astonishingly short time, he had performed this task, and Ruboto was born. Thanks to the efforts of several other developers, Ruboto has become an active project that is growing increasingly intriguing to Android and Ruby developers alike.
Today, Ruboto comes in two flavors: ruboto-irb and ruboto-core. ruboto-irb is an interactive Ruby shell that runs on Android. This project lets you run arbitrary Ruby scripts that can also access Android APIs. This tool may be very useful for developers who want to run tests or perform tasks on their device, but is probably not appropriate for writing applications that you later distribute.
In contrast, ruboto-core provides a framework that lets you create your own Ruboto projects. Using ruboto-core, you can add powerful and flexible scripting support to your project, while retaining access to the Android APIs. Figure 1 shows the ruboto-core build process: auto-generated Java source files and your custom-written Ruby scripts get packaged together into an Android APK that will run on the device.
Figure 1. Constructing a Ruboto app
The remainder of this article focuses on creating a custom Ruboto-based project. Ruboto is still early software; as of this writing, its version number is 0.0.2. It continues to evolve quickly, and may behave slightly differently by the time you read this article. If you encounter issues while running any of the commands below, please see Resources to get the most up-to-date information on Ruboto and Android.
Bringing together Ruby and Android lets you create simple scripts that can access Android's powerful functions. You will write a Ruboto script that lets users order seafood from a delivery service. This simple application takes advantage of the strengths of each platform. On the Android side, you will have a simple way to create an SMS message containing your order; the application places orders without even requiring a server. On the Ruby side, you will re-use an existing language processing library that will normalize your orders into a readable format.
To build and deploy your Ruby scripts on Android requires several components. You may already have some of these installed; if so, you can use those existing tools.
Because both Android and Ruby are multi-platform, you can run Ruboto on Linux®, Mac OS X, or Windows®. You will use the command line throughout this article.
If you use cygwin for Windows, you may encounter problems while running
certain JRuby commands. To be safe, stick with the standard Windows CMD
shell if you are running Windows.
You will need a working Java Development Kit (JDK) on your development box. To check if one is already installed, enter the following command:
$ javac -version |
If this command finds a version of the JDK, you are set. If not, install the latest version of the JDK from the link in Resources. After installation, add the JDK's bin folder to your PATH and repeat the above command.
Android ships with its own version of Ant, but Ruboto will need to access Ant as well from its own scripts. If you don't have a stand-alone version of Ant installed, download it from the link in Resources and unzip to any folder. Again, add its bin folder to your PATH. Make sure you can run the Ant command.
Go to the Android Developer Site and install the Android SDK for your
operating system (see Resources). After this
installs, run the android command located in
Android's tools folder. This launches the SDK manager, as shown in Figure 2. You will want to install the following
packages, which are listed under Available packages.
- SDK Platform Android 2.2, API 8
- Android SDK Tools, revision 8
- Android SDK Platform-tools, revision 1
Figure 2. Android SDK and AVD Manager
Create an Android image for development by opening the Virtual devices section of the Android SDK and AVD Manager. Referring to Figure 3, create a virtual device named Froyo that targets Android 2.2 - API Level 8. You can create a virtual SD Card if you like.
Figure 3. Creating an emulator
Ruboto apps will run on your device, but development will be much easier if you have write access to arbitrary folders, which requires either using the emulator or a rooted device. The rest of this article focuses on using the emulator. After you finish the project, it will run equally well on an Android device running software version 2.2 or later.
Add Android's platform-tools and tools directories to your PATH. You should now be able to run the commands in Listing 1 from your prompt.
Listing 1. Running commands from your prompt
$ aapt version $ adb --version |
JRuby offers an incredibly easy installation. Simply go to http://jruby.org/getting-started and follow the directions. If necessary, add the JRuby bin folder to your PATH. Verify that the installation succeeded by typing the following command:
$ jruby -v |
Because Ruboto is hosted on a secure server, you'll need to install the jruby-openssl gem to download it. You can do this with the following command:
$ gem install jruby-openssl |
You will also want to install rake, Ruby's equivalent to make or ant. Type the following command:
$ gem install rake |
Finally, it's time to install Ruboto itself. Ruboto comes packaged as a gem, so installation is easy. Enter the following command:
$ gem install ruboto-core |
Ruboto will create an Android project from scratch for you, which ensures that your manifest is set up correctly, scripts are placed in the right collection, and you have access to the necessary libraries. You should take this approach rather than trying to create it yourself or modifying an existing Android project.
To create the project, move to a project folder, then type the following:
$ ruboto gen app --package us.cirion.ruboto.demo --path fishmonger --name Fishmonger --target android-8 --activity Fishmonger
This command does the following:
gen apptells Ruboto to create a new Android project from scratch.--packageprovides the unique Android package name.--pathtells Ruboto where to store the project; this must be a new folder name.--namedefines the user-visible name of the application; this does not need to be unique.--targetspecifies which Android version to compile the project against. As of this writing, you must useandroid-8. An optional argument,--min_sdk, declares that your application can run on earlier Android versions; omit this for now.--activityis an optional argument that tells Ruboto to generate a new Android activity and initialize it.
You can explore the contents of the fishmonger directory. Ruboto has
automatically generated all of the Android files necessary to build and
run a basic Activity. Because the application will send SMS messages, you
do need to make one change within the AndroidManifest.xml file. Insert the
following tag as the first child of the <manifest> element in that
file:
<uses-permission android:name="android.permission.SEND_SMS" /> |
If you omit this permission, you will still be able to build and load your script, but you will get a run time error when your application tries to send an SMS message.
Out of the box, Ruboto generates an Activity and script that will install and run on the device or emulator. If your emulator is not already running, you can launch it with the following command:
$ emulator -avd Froyo |
Wait for the emulator to finish booting to the home screen. To ensure all
Ruboto files get built and deployed properly, cd to the fishmonger
directory and run the following command:
$ rake install |
If you encounter an error, try running the command again; sometimes the connection times out during the build process. The initial build takes a while, but later updates happen more quickly. After the installation completes, look for the icon labeled Fishmonger in your emulator. Launch it and wait. As of this writing, the Ruboto engine takes a while to load. Eventually, you will see a screen similar to Figure 4 display.
Figure 4. The template Ruboto activity
Now, let's set up the Fishmonger app. First, you'll add natural language support. Ruby has an excellent gem called linguistics that offers many English-language capabilities. As of this writing, Ruboto does not handle the nested directory structure of the linguistics library, so please download this article's linguistics zip file instead and unzip the contents into fishmonger\assets\scripts (see Downloads for a link). This is the stock linguistics gem, modified to flatten out the directory structure. In the future, you should be able to just bundle the gem with your ruboto script.
You're now ready for the meat of the project. The Ruboto framework takes care of all the Java code and Android infrastructure, so all of your work can take place in fishmonger.rb. Erase the default contents of the file. You'll start by adding the text in Listing 2.
Listing 2. Script dependencies
require 'ruboto.rb' require 'linguistics' include Linguistics::EN import "android.telephony.SmsManager" ruboto_import_widgets :Button, :EditText, :LinearLayout, \ :RadioGroup, :RadioButton, :TextView |
The first two lines load the ruboto and linguistics libraries. The include command will make English language grammar available in your module.
The first import will look familiar to JRuby users: you are adding support for another class. Note that in this case, you're actually using an Android Dalvik class, not a part of the standard Java library. Ruboto will use reflection at run time to load this class and make it available to you.
ruboto_import_widgets behaves similarly. Here,
you're adding some Android-specific UI widgets. These are commonly used in
Android activities, and Ruboto adds some convenience methods that let you
more easily configure the UI.
Next, define the script's handle_create method, as shown in Listing 3.
Listing 3. Configuring the screen
$activity.handle_create do |bundle|
setTitle 'Freddy\'s Fresh Fish'
setup_content do
linear_layout :orientation => LinearLayout::VERTICAL do
text_view :text => "What would you like to order?"
@group = radio_group do
radio_button :text => "Tuna", :id => 0
radio_button :text => "Trout", :id=> 1
radio_button :text => "Salmon", :id => 2
radio_button :text => "Crab", :id => 3
radio_button :text => "Lobster", :id => 4
end
@quantity = edit_text :hint => "Quantity"
button :text => "Place Order"
end
end
|
handle_create gets called when the user launches
the application. In Android, this is where you handle the necessary setup.
Standard Android applications generally use XML to define the layout, but
in Ruboto, you'll script it instead.
Again, take advantage of Ruboto's functions that provide a bridge between
your script and Android. Regardless of your background with Ruby or
Android, you should be able to see what's happening within
setup_content. You are creating a vertically
oriented layout that stacks several widgets on top of each other. This
includes text, radio buttons for choosing the type of fish to order, an
editable text field for entering the quantity, and a button to place the
order. You can use Ruby syntax for configuring your widgets, instead of the
more verbose Java syntax generally used in Android.
Setting the id attribute on each radio_button is a bit of
a hack; it gives you an easy way to later look up which button was
selected.
Android will automatically handle all user interaction with the radio buttons and editable text field. The only piece left to define is handling the Place Order button, shown in Listing 4.
Listing 4. Placing an order
handle_click do |view|
if view.text == "Place Order"
count = @quantity.text
food = @group.child_at(@group.checked_radio_button_id).\
text.downcase
order = Linguistics::EN::plural(food,count)
SmsManager.default.send_text_message("4155551234", \
nil, "Please send #{count} #{order}", nil, nil)
finish
end
end
end
|
If you have previously written Android applications, you'll notice that
you're using a different paradigm for handling selection. Android
developers tend to write unique click handlers for each selectable item.
In Ruboto, though, it's easier to create a global click handler for your
Activity, and within there to test for which
item the user clicked.
You extract the number and the type of fish that the user chooses. If they
did not check a radio button, Ruboto will internally handle the run time
error gracefully. Otherwise, you will pass off the text to the linguistics
library and ask it to create the proper noun form for you. The library can
handle the different rules for pluralization, so it will generate values
like 1 salmon,
2 salmon, 1 crab,
2 crabs, and so on. It even recognizes written
numbers, so it will also create phrases like
one lobster,
three lobsters, and so on. This is very
impressive behavior for a single line of code and shows the power of
leveraging existing scripts to easily add capabilities to your
application.
Likewise, sending an SMS message requires only a one-line call to a convenient
Android method. Ruboto lets you use Ruby-style syntax to invoke this
method; the Java code equivalent would be
SmsManager.getDefault().sendTextMessage(). You
provide the recipient's phone number and the text to send, and pass nil
for the optional parameters. If you are running on a device and would like
to actually send an SMS message, substitute a valid phone number. If you
want to test in the emulator, you can substitute an emulator's port
number, such as "5554."
One of the most powerful aspects of Ruboto is that you can change functionality by simply loading an updated script. Even though you have completely changed what this application does, you do not need to rebuild the application or reload the APK. Instead, type the following at the command line:
$ rake update_scripts |
This will copy the linguistics scripts and your new fishmonger script to the emulator or an attached device. When you relaunch the application, you will see your new screen, as shown in Figure 5.
Figure 5. Android ordering page
If you are running a non-rooted device or make any changes to the Java
files or the Android manifest, you can load the update by typing the rake
installation command again. Note that even non-rooted devices can update their scripts
on the fly; for example, you could download new scripts from the Internet
or generate them at run time. The firmware limitation only applies to
pushing files over your USB connection.
Go ahead and play around with the application. After you make a valid selection and press the order button, the screen will automatically close. If you used a valid recipient address, they will shortly see your message arrive. Figure 6 shows the very busy fishmonger's list of recent orders.
Figure 6. Standardized orders from Ruboto script
Ruboto is still an early effort, but even in its current state it provides a very useful and flexible way to write and distribute Android software. Ruboto's success results from the strengths of JRuby and Android: JRuby has already done the hard work of writing a full Ruby interpreter in the Java language, and Android's Dalvik toolchain provides an impressive conversion from standard Java bytecode to its custom Dalvik bytecode.
As you've seen, Ruboto scripts can be extremely short, while offering strong capabilities from both Ruby and the Android. The ability to mix and match Ruby scripts, Ruby and Java syntax, and Android APIs gives you many options for increased productivity.
Ruboto is a compelling bridge to developers on both sides of the client/server divide. Android developers will appreciate its reflective powers, which give them the ability to dramatically update application capabilities on the fly. Ruby developers have gained a fairly painless way to bring their scripting expertise to the mobile platform and can leverage existing Ruby code to create new applications. Both camps will be watching with great interest as this project further matures.
| Description | Name | Size | Download method |
|---|---|---|---|
| Article source code | fishmonger.zip | 65KB | HTTP |
| Article source code | linguistics-rb.zip | 34KB | HTTP |
Information about download methods
Learn
- Learn more about JRuby.
- View the excellent Google I/O video on
the Dalvik
VM and Dalvik bytecode.
- Access ruboto-core project
information.
- Learn about ruboto-irb, the
sister project that offers an interactive ruby interpreter.
- For an alternative approach to Ruby on
Android, explore Mirah and Garrett. These
compile Ruby scripts to the Java language (and thence to Dalvik), rather than interpret
Ruby scripts at run time. This approach leads to faster execution, at the
expense of run time metaprogramming flexibility.
-
"Introduction to Android Development" (developerWorks, May 2009)
gives you an introduction to the Android platform and
explains how to code a basic Android application.
-
"Networking with Android" (developerWorks, June
2009) explores the networking capabilities of Android.
-
"Working
with XML on Android" (developerWorks, June 2009) explains the different options for working with XML on Android and how
to use them to build your own Android applications.
-
Under the Hood of Native Web
Apps for Android: Learn about hybrid applications in Android.
-
Mobile Design and
Development by Brian Fling from O'Reilly Media discusses practical
guidelines, standards, techniques, and best practices for building mobile
products.
- Get the Android
SDK documentation.
-
The Open Handset
Alliance is Android's sponsor.
- The developerWorks Web Development zone
specializes in articles covering various web-based solutions.
Get products and technologies
-
Download the Android SDK,
access the API reference, and get the latest news on Android from the
official Android developers' site. Version 1.5 and later will work.
- Android is open
source, which means you can get the source code for it from the Android Open Source Project.
- Get JDK 6 Update 21.
- Download Ant.
- Innovate your
next development project with IBM trial
software, available for download or on DVD.
Discuss
-
Discuss Ruboto with
the development team and other early adopters.
- Create your developerWorks profile today and set up a watchlist on mobile web application development. Get
connected and stay connected with developerWorks community.
- Find other developerWorks members interested in Web development.
- Share what you know: Join one of our developerWorks groups focused on Web
topics.
- Roland Barcia talks about Web 2.0 and middleware in his blog.
- Follow developerWorks' members' shared bookmarks on Web topics.
- Get answers quickly: Visit the Web 2.0 Apps forum.
- Get answers quickly: Visit the Ajax forum.

Chris King is a software engineer specializing in mobile development. He is the author of Advanced BlackBerry Development, Advanced BlackBerry 6 Development, and Android in Action, Second Edition.



