In late 2008, I spent two days trying to get Python running on my Android G1. When that stalled, I tried Lua instead — and had it cross-compiled and running in an afternoon. That small win kicked off a project that eventually became an official Google open source release and put scripting languages on hundreds of thousands of Android devices.

Getting Lua and Python onto Android

The G1 ran Android 1.0 on a 528 MHz ARM processor with 192 MB of RAM. There was no NDK yet. Cross-compiling anything for Android meant building the full Android source tree, grabbing the agcc wrapper script, and patching out every localeconv() call that bionic’s libc didn’t support.

Lua was the easy one — two small patches to llex.c and lvm.c to replace localeconv and strcoll, a cross-compile with agcc, and adb push to /data. It ran on the first try.

Python 2.4.5 was harder. The build system assumed it could run the interpreter it was building (for pgen and compileall.py), so I had to split the build into a host Python and a target Python with HOSTPYTHON and HOSTPGEN variables patched into the Makefile. The posix module had to be ripped out entirely — bionic didn’t support half the POSIX calls it needed. Several modules (_ssl, readline, _curses, zlib) were disabled. After two days of patching pwdmodule.c, socketmodule.c, fileobject.c, and pystrtod.c, Python booted on the phone.

Wrapping It Up: ASE

Once I had interpreters running, the obvious next step was making them actually useful — not just a shell on a phone, but a way to script Android itself. I built the Android Scripting Environment (ASE), a host app that provided:

  • An on-device script editor and terminal
  • A JSON RPC bridge between scripts and Android APIs (sensors, location, SMS, Bluetooth, TTS, camera, contacts, WiFi, and more)
  • A la carte interpreter installation (Python, Lua, Perl, JRuby, BeanShell, Tcl, JavaScript via Rhino, and Shell)
  • Script sharing via QR codes — scan a barcode, get a running script
  • Shortcuts and widgets to launch scripts from the home screen

The key architectural idea was the RPC layer. Scripts in any language could call droid.makeToast('hello') or droid.startLocating() without knowing anything about Android’s Java APIs. The AndroidProxy class exposed annotated @Rpc methods over a local JSON-RPC server, and each language got a thin client module.

ASE launched in June 2009 with a post on the Google Open Source Blog. The reception was immediate — it hit Hacker News, Reddit, and the Android developer community hard.

The Evolution: r8 through r25

Over the next year, ASE went through rapid iteration. A few highlights from the release cycle:

Interpreter expansion. What started as Python and Lua grew to include Perl, JRuby, BeanShell, Tcl, JavaScript (via Rhino), and Shell. JRuby was painfully slow — up to a minute for the first startup on a G1 — but it worked.

API surface growth. The facade started with location and sensors. By r25, it covered SMS (send, read, manipulate), Bluetooth (including binary read/write via base64), camera and video, WiFi scanning, screen brightness and timeout, battery management, airplane mode, DTMF tone generation, contact database access, media volume control, cell tower location, and various UI dialogs (date picker, time picker, seek bar, spinner).

Developer experience. The built-in editor gained Save & Run, auto-completion of brackets and quotes, and an API browser with code generation (long-tap a method to insert a call). The terminal got fullscreen mode and multiple font sizes. A logcat viewer was added. Scripts could run in the background, and a Script Monitor let you view, stop, and reconnect terminals to running scripts.

Triggers. Scripts could be scheduled to run periodically or in response to events (ringer mode changes, phone state).

Script sharing. Beyond QR codes, ASE added Locale plugin support (trigger scripts from Locale conditions) and live folders on the home screen.

Becoming SL4A

In July 2010, ASE was renamed to Scripting Layer for Android (SL4A). The rename reflected a shift in architecture: interpreters were split out into separate APKs, and SL4A became a focused runtime layer. The key addition in the SL4A era was the WebView API, which let scripts build actual GUIs using HTML/JavaScript backed by Python or any other interpreter. Scripts could also be packaged as standalone APKs that didn’t require SL4A to be installed.

SL4A continued through r3, adding context menus (later replaced with quick-action bubbles), folder support in the script manager, and in-process interpreter support. The last release in this sequence was October 2010.

What People Built

The most satisfying part of running an open source project is seeing what people do with it. ASE/SL4A users built:

  • Automated data logging to your.flowingdata with home screen shortcuts for “goodmorning” and “goodnight”
  • DTMF dialers for placing calls through landlines
  • Home automation controllers
  • Bluetooth serial bridges to Arduino and LEGO NXT robots
  • GPS loggers and geocaching tools
  • SMS autoresponders

The project’s niche was clear: it wasn’t for building polished apps. It was for people who wanted to script their phone the way they’d script a Linux box.

From Scripting to Robots

SL4A had an unexpected second act. Because it ran a full Python interpreter on Android, it became the first way to load ROS onto a phone — you could run rospy on SL4A and suddenly an Android device was a ROS node with cameras, GPS, an IMU, and a cellular radio. People started strapping phones to robots as cheap sensor packages, and projects like Cellbots (Ryan Hickman’s work) used SL4A to bridge Android to LEGO NXT bricks and Arduino boards over Bluetooth.

But running rospy on SL4A had real limits. Python on a 1 GHz ARM chip with 512 MB of RAM was slow, and the scripting layer added overhead on top of that. The experience convinced me that if ROS was going to run well on Android, it needed a native Java implementation — not a Python interpreter shoehorned onto a phone. That’s what led me to build rosjava, a pure Java implementation of ROS that ran natively on Android without SL4A in the loop.

Rosjava launched at O 2011 alongside Android’s Open Accessory API, and the cloud robotics work grew from there — talks at Berkeley, Devoxx, and ROSCon, and eventually Cartographer, a SLAM backpack that mapped building interiors for Google Maps. Cartographer’s Android tablet interface and parts of its infrastructure were built on rosjava. The line from “Python on a G1” to “real-time SLAM on a backpack” is surprisingly direct.

Looking Back

ASE was the right project at the right time. In 2009, Android was new, the app ecosystem was young, and the idea that you could write a Python script on your phone and have it send SMS messages was genuinely novel. The JSON RPC bridge was a pragmatic hack — it let us support any language without writing Java bindings for each one — and it held up well through the transition into robotics and beyond.