I wanted to try the RubyMotion Flow gem the other day and especially the Android part of it. Problem was how to test the Android app for development without having to buy and Android device. There is the built in emulator in the Android SDK, but after waiting for hours for it to boot up I lost faith and interest in it.

I tested some other alternatives, but all of them had some major drawbacks:

  • BlueStacks collided with my local Docker installation and crashed my MacBook completely. Also I am not sure if you can use it for debugging.
  • Andyroid installed MacKeeper on my Mac which I consider malware and that’s also why I am not linking to it. I would recommend to KEEP YOUR HANDS OF ANDYROID!
  • Xamarin Android Player seemed to show quite good performance, but it is no longer supported by Xamarin.

So my plan was to setup a VirtualBox machine for RubyMotion development. Probably this setup does not make for a good, performant development setup for production. However, if you would like to do a quick test of RubyMotion’s Android capabilities it is a cheap (free) solution.

Setting up VirtualBox

For a more detailled guide on how to install Android in VirtualBox follow this guide Install Android 5.1 on VirtualBox - Ricky Ford. It also works with more recent versions of Android.

  1. Download and install VirtualBox
  2. Download Android Image file from http://www.android-x86.org. I chose the “Android-x86 6.0-r1 live and installation iso (32-bit)” image
  3. Install Android to a new virtual machine in VirtualBox. Here is a quick overview of the settings: Vb Settings

Preparing the virtual device for debugging

Next we need to enable Developer mode in Android:

  1. Go to Settings -> “About tablet”
  2. Click on build number 7 times to enable developer mode
  3. Go to Settings -> “Developer Options”
  4. Turn on “USB debugging”
  5. Go back to Settings -> “Security” and enable “Unknown Sources” to allow installation of apps

Connecting to the device for RubyMotion development

Lastly we need to connect to the virtual device so that we can run and install apps to it via the RubyMotion rake command.

First let’s connect the Android Debug Bridge (ADB) to our virtual device:

Enable port forwarding in VirtualBox: Go to the “Oracle VM VirtualBoxManager” window, select your Android box and click on “Settings” in the toolbar. Vb Settings@2x

Select the “Network” option, collapse the “Advanced” section and click on Port Forwarding Vb Network Advanced@2x

Forward the Host Port 5555 to the Guest port 5555, click Ok twice to enable the new settings Vb Port Forwarding@2x

Go to the terminal and connect adb to your VirtualBox Android device with the following command:

$ ~/.rubymotion-android/sdk/platform-tools/adb connect localhost:5555

Create the app and run it

Now let’s create a “Hello Android” app as detailled in the RubyMotion Getting Started guide:

$  motion create --template=android Hello
    Create Hello
    Create Hello/.gitignore
    Create Hello/app/main_activity.rb
    Create Hello/Gemfile
    Create Hello/Rakefile
    Create Hello/spec/main_spec.rb

Go the new project dir and change your main_activity.rb file to:

class MainActivity < Android::App::Activity
  def onCreate(savedInstanceState)
    puts "Hello World!"
    super
    view = Android::Widget::TextView.new(self)
    view.text = "Hello Android!"
    self.contentView = view
  end
end

Now let’s try to install your RubyMotion application to the virtual Android device by running the following command in your RubyMotion project dir:

$ rake emulator
    Create ./build/Development-25/classes.dex
    Create ./build/Development-25/Hello.apk
      Sign ./build/Development-25/Hello.apk
     Align ./build/Development-25/Hello.apk
   Install ./build/Development-25/Hello.apk
    ERROR! Cannot install an app built for API version 25 on a device running API version 23

Ok now the RubyMotion default template tries to build for API version 25, but our device runs version 23. We need to fix this by changing the API version in our Rakefile:

# -*- coding: utf-8 -*-
$:.unshift("/Library/RubyMotion/lib")
require 'motion/project/template/android'

begin
  require 'bundler'
  Bundler.require
rescue LoadError
end

Motion::Project::App.setup do |app|
  # Use `rake config' to see complete project settings.
  app.name = 'Hello'
  app.api_version = '23'
end

Now let’s try again and everything should work as expected:

$ rake emulator                                                      
    Create ./build/Development-23/classes.dex
    Create ./build/Development-23/HelloAndroid.apk
      Sign ./build/Development-23/HelloAndroid.apk
     Align ./build/Development-23/HelloAndroid.apk
   Install ./build/Development-23/HelloAndroid.apk
     Start com.yourcompany.helloandroid/.MainActivity
--------- beginning of main
--------- beginning of system
04-19 12:02:38.493  2786  2794 E art     : Thread attaching while runtime is shutting down: Binder_1
(main)> 

The app should show up in the homescreen: Android Homescreen@2x

And the app should work as expected: Android Hello Android@2x