Mobile applications are everywhere these days, and the clear leader in the mobile operating systems arena is Google’s Android with over 80% of the smartphone OS market.
As such, the development and testing of Android applications for various Android versions and devices, with all the associated challenges in them is becoming an increasingly important topic.
A clear need in day-to-day dev and test processes is the ability to spin up various android versions on multiple mobile and tablet device types, while developing, manually and automatically testing apps under development. A common way to do so is by using the official Android Emulator from Google. The emulator can run pretty much every Android version, emulates various hardware features and in general is very robust. The downside for using it though was the emulator performance – it used to be painfully slow compared to a real device.
Luckily, thanks to the incorporation of hardware acceleration for virtualization support in the emulator, it has become much faster recently.
However, it is impossible to run the Android emulator in the public cloud (for example in Amazon’s EC2 or Google’s Cloud Engine) in the accelerated mode due to lack of support for such hardware features (namely Intel’s VT or AMD’s SVM), so the only real option to run it (when it isn’t painfully slow) is on dedicated physical hardware which lacks any elasticity and requires a large up-front investment.
Well, NOT ANYMORE. Thanks to Ravello’s full nested virtualization support, you can actually run the Android emulator (as-is) with hardware acceleration in any public cloud!
Lets see how.
We will first create a VM on top of Ravello for the purpose of serving as the host for the Android Emulator, then install the emulator on it, configure a device, and run it while allowing for direct VNC access to it.
Create a host VM in Ravello (on AWS) for the Android emulator
For the sake of this blog post, I’ve chosen to use Xubuntu 14.04.1, as I wanted to use some of the Android emulator’s graphical tooling while using the lightweight Xfce desktop manager. In many settings where you will not need a graphical desktop, you can simply use Ubuntu Server instead.
The easiest way to get a Xubuntu 14.04.1 up and running on Ravello is by installing it from a CD-ROM.
- Download the installation ISO from the above link
- Upload it to Ravello as a disk image. See How to use an ISO file as a CD-ROM in your Ravello application for instructions.
- Create a new application in Ravello (We’ll call it “Ubuntudroid”)
- Drag the “Empty” VM from the library to the canvas
- Rename the VM (e.g. to “Ubuntudroid”)
- Open the VM Editor for this VM and perform the following changes:
- General: 2 CPUs, 4GB RAM
- Networks: Change eth0’s device type to virtio
- Disks: Change hda to the virtio device type ; Mount the Xubuntu14.04.1 image into the CDROM drive
- Click Save to close the editor
- Turn on Nested^2 (SVM) support for this VM in Ravello as described in Enabling Nested Virtualization on Ravello VM Image.
- Click Publish to publish this single VM application to the cloud, you can stick to Cost Optimized mode, or choose the cloud and region of your liking by using the Performance Optimized mode.
- Wait 5-10 minutes for the VM to be Started. Open the Console to it and follow the graphical installation to install the OS to disk. It is highly advised to install an SSH server on this VM once it is installed for easier maintenance by running (shell):
sudo apt-get install ssh
- Now we will enable full virtualization support for the emulator on this Ubuntu VM by loading the KVM module. Do so by running the following commands:
sudo modprobe kvm_amd sudo chmod 666 /dev/kvm
- You can make sure that KVM is running correctly by running
lsmod | grep kvm
and verifying that the module is loaded.
Install the Android Emulator on the newly created VM in AWS
You should open a shell session (either by SSHing to the VM, or using the direct console connection).
- Install OpenJDK
sudo apt-get install openjdk-6-jre openjdk-6-jdk icedtea6-plugin
- Download the latest Android SDK (Linux 32 & 64 bit SDK only) by running the commands below. At the time of writing, this was the newest Android SDK, but you can always find the newest one here.
- Extract the downloaded archive by running
tar -xvzf android-sdk_r23.0.2-linux.tgz
- Run the following (better to do it from a graphical session, e.g. console) to install it
cd ~/android-sdk-linux/tools ./android
And that’s basically it, we have now a working VM with the Android emulator installed on it. It is highly advised to update your SDK (you will see the option in the android SDK Manager), and install some different API level versions for x86 platforms (e.g. API Level 19 for Android 4.4.2).
Create an AVD
Now we will create a new AVD (Android Virtual Device) to run on our emulator. The easiest way to do so is by running (in a graphical session):
You will get to a screen similar to the one below, just without any AVD defined:
Click on Create… to create a new AVD.
Give it a name, and choose the device type and various settings that you would like to use, as shown for example below.
It is advised to use at least 512MB if not 1024MB of RAM, and to use the “Snapshot” emulation option.
Run the Emulator
To run the android virtual device with a local display (to the ravello console), you can simply run (from the tools directory):
sudo ./emulator64-x86 -avd [AVD Name] -noaudio -nojni -netfast -no-boot-anim -qemu -enable-kvm -snapshot
The various flags are turning on various optimizations in the emulator, as well as enabling KVM usage for virtualization hardware acceleration.
You will now see the android device booting, and after a few seconds you will get to the android home screen, decorated by the skin that you are using.
Enable direct VNC connection to the AVD
In many cases, you would like to be able to allow for direct VNC connection to this AVD, either using a VNC client, or by using a VNC to HTML5 gateway such as Guacamole or NoVNC to enable direct access to the Android device from any web browser.
In order to do so, we will spawn a VNC server per AVD, and set the DISPLAY for the AVD process to the one the VNC server will use.
For this, first we will install a VNC server, we choose to use the standard x11vnc, but you can choose to use other implementations as well (such as TigerVNC, TightVNC or RealVNC). We will install the server by running:
sudo apt-get install vnc4server
Now, we will change the way that we spawn AVDs, to first create a VNC server on a specific display, and launch the android emulator using this display.
For example, running:
vncserver -kill :2 # if there’s a vncserver on this display, kill it vncserver -depth 24 :2 -geometry 800x600 # create a new vncserver on :2 DISPLAY=localhost:2 sudo ./emulator64-x86 -avd -noaudio -nojni -netfast -no-boot-anim -qemu -enable-kvm -snapshot
Now, we need to add an external service in the Ravello management console to allow external traffic to reach this VNC Server, in the above example on port 5902 (as the VNC port by default is 5900+Display). Make sure to Update your application after you’ve added this port. Now you can connect to it using your favorite VNC Client.
You can of course run multiple android emulators (and VNC servers) on a single VM, just make sure the display numbers are unique.
One of the cool use-cases for running Android in the cloud is to enable continuous integration for Android.
About Ravello Systems
Ravello is the industry’s leading nested virtualization and software-defined networking SaaS. It enables enterprises to create cloud-based development, test, UAT, integration and staging environments by automatically cloning their VMware-based applications in AWS. Ravello is built by the same team that developed the KVM hypervisor in Linux.