DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. How to Develop Android Apps Using Ruby

How to Develop Android Apps Using Ruby

Like many other language created for the web, Ruby is going mobile. Read on to learn how to use RubyMotion to create mobile apps written in Ruby.

Ram Manusani user avatar by
Ram Manusani
·
Dec. 21, 18 · Tutorial
Like (5)
Save
Tweet
Share
34.50K Views

Join the DZone community and get the full member experience.

Join For Free

The way mobile apps are developed has dramatically changed over the past decade. Mobile apps were built using native technologies like Android and iOS and then came mobile frameworks like Titanium and PhoneGap that allowed JavaScript developers to build hybrid mobile apps with a sustained framework limitation. Ever Since RubyMotion was released, Ruby developers have been building cross-platform native apps for iOS, Android, and OS X using the Ruby language alone, without any framework limitations.

An important skill to have when creating Android applications is to have an understanding of Java programming, the required Java packages, and the Android SDK. Learning this narrow set of skills could be challenging for someone new, and the Ruby language has a solution for Ruby developers or someone new wanting to learn the Ruby language in the form of RubyMotion.

What is RubyMotion? It's a Ruby language implementation that is compiled to run on iOS, OS X, and Android supported devices with a unified runtime approach and optimized binary support using an ahead-of-time static compiler. RubyMotion also includes testing tools, interactive debugging support optimized and designed for embedded device constraints that can quickly be learned by Ruby developers.

RubyMotion is considered a combination of runtimes since it is tightly integrated with Android runtime and uses the command-line interface (CLI) to develop Android apps interactively. This article will make developing Android apps easier for Ruby developers, and make Android developers more productive. This article will take you through RubyMotion by developing an Android app that links movie names to Wikipedia; let’s call it Moviepedia.

Let’s start with the installation part first.

Installation and Setup

RubyMotion comes in multiple flavors ranging from hobbyist to professional and picks the package that is right for you to get started. I will use the starter package for simplicity, download the RubyMotion Installer, and follow the steps below. First, double-click the RubyMotion Installer.

Agree to the End User License Agreement and enter the license key sent to your email address during the installation and the installer will resume the installation process as shown in the screen below

Look for the successful install confirmation before you close out the installer.

IF at any point you run into trouble, RubyMotion support is available on @RubyMotion’s Twitter account. Additional help and resources are available in case any assistance is needed from the RubyMotion community.

  • RubyMotion Community Forums
  • RubyMotion Google Groups
  • RubyMotion Slack Channel
  • FAQ

To verify that RubyMotion is successfully installed on your machine, run the following command:

$ motion --version 5.9

If at any time you want to upgrade to a newer version:

$ motion update

Installing Java

The RubyMotion build system requires the Java compiler to be installed; follow these steps if you don’t have one installed. To verify Java is installed successfully, run the following command:

$ java -version
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)

Install Android Environment

A single line command is used to set up the Android environment using the android-setup command. This will download both the Android SDK and Android NDK under the ~/.rubymotion-android directory and select the SDK version of your choice or pick the latest one if you are not sure.

$ motion android-setup

You should see an output similar to the screen below during the SDK installation

The Android SDK (Software Development Kit) provides a selection of tools to build Android applications which require Java to be installed as a pre-requisite. The Android SDK ecosystem contains the following for mobile app creation:

  • Build-tools
  • Platform-tools
  • Android Debug Bridge (ADB)
  • Android Emulator

The Android NDK (Native Development Kit) provides tools for Android devices to integrate with the Android SDK compilation tool.

Now that we have the Android SDK and Android NDK installed, let’s start creating our new RubyMotion app, Moviepedia

Project Creation: Moviepedia

Similar to Rails, RubyMotion works through the command line for app creation. Open up the terminal and navigate to the folder of your choice to start creating the app using the motion create command. The motion create command, by default, creates iOS application templates and explicitly calls out Android keywords that will create an Android application with the application name specified, which in our case is Moviepedia.

$ motion create --template=android Moviepedia

After successfullly running these commands, you should see a creation action similar to the below screenshot:

Navigate to Moviepedia project directory using the cd Moviepedia from the current directory and let’s understand the files created.

  • Moviepedia/app directory: app directory contains all the ruby code with a *.rb file extension
  • Moviepedia/app/main_activity.rb file: This file contains the fundamental lifecycle callback methods. Rubymotion creates onCreate() method which gets fired when the system initially creates the activity and check the visual lifecycle of android app activity below to understand the further steps after onCreate callback gets initiated
  • Moviepedia/spec directory: spec directory includes automated tests that are automatically generated and rake spec command will run all .*rb files included inside the spec directory.
  • Moviepedia/.gitignore file: gitignore file is used by Git repository system to ignore file tracking on the files mentioned
  • Moviepedia/Gemfile: Gemfile lists all the gem dependencies that are needed for our application to run sourced from https://rubygems.com . Rubymotion defaults rake gem to run our application
  • Moviepedia/Rakefile: Rakefile contains the application name, SDK, NDK, device location which is run by a rake command.

Android Lifecycle

Install dependencies

Since Rubymotion apps contain a Gemfile, all the required application dependencies mentioned in the Gemfile should be installed before running or building the app. Run the bundle command to install the Gemfile dependencies

$ bundle install


Using rake 12.3.1


Using bundler 1.16.0.pre.3


Bundle complete! 1 Gemfile dependency, 2 gems now installed.


Use `bundle info [gemname]` to see where a bundled gem is installed.

Running a gemfile will create a Gemfile.lock which contains a snapshot of all the gem(s) along with their associated dependency versions.

Build the App

The rakefile is the first file loaded by RubyMotion when the app builds initially with all the application properties and load configurations included. Check the default Rakefile with the application name mentioned in the App.Setup section.

#- * -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 = 'Moviepedia'
        end

Let’s fire up the terminal to understand the rake options. The rake config specifies the application defaults and is self-explanatory and customizable as needed.

$ rake config
api_version            : "27"
  application_class      : nil
  archs                  : ["armv7"]
  assets_dirs            : ["./assets"]
  build_dir              : "./build"
    features               : []
    files                  : ["./app/main_activity.rb", "./app/movies.rb"]
    icon                   : nil
    logs_components        : ["com/yourcompany/moviepedia:I", "AndroidRuntime:E", "chromium:E", "dalvikvm:E", "Bundle:E", "art:E"]
    main_activity          : "MainActivity"
      main_dex_list          : nil
      manifest               : {"xmlns:android"=>"http://schemas.android.com/apk/res/android", "package"=>#<Proc:0x007fa61a16d358@/Library/RubyMotion/lib/motion/project/template/android/config.rb:146 (lambda)>, "android:versionCode"=>#<Proc:0x007fa61a16d2e0@/Library/RubyMotion/lib/motion/project/template/android/config.rb:148 (lambda)>, "android:versionName"=>#<Proc:0x007fa61a16d218@/Library/RubyMotion/lib/motion/project/template/android/config.rb:149 (lambda)>}
motiondir              : "/Library/RubyMotion"
  multidex               : false
    name                   : "Moviepedia"
      ndk_path               : "/Users/.rubymotion-android/ndk"
        optional_features      : []
        package                : "com.yourcompany.moviepedia"
          permissions            : []
          resources_dirs         : ["./resources"]
          sdk_path               : "/Users/.rubymotion-android/sdk"
            services               : []
            specs_dir              : "./spec"
              sub_activities         : []
              support_libraries      : []
              target_api_version     : "27"
                theme                  : "@android:style/Theme.Material.Light"
                  version_code           : "1"
                    version_name           : "1.0"

You can specify the rake configuration if you want to modify and not stick to the defaults explicitly. Check some config examples changes below to provide custom values as configuration settings.

app.api_version = '26' # Will change the api version to 26 from 27

app.sdk_path = '/.rubymotion-android/sdk' #SDK path change

app.version_name = '2.0' # Change the version name

app.main_activity = 'NewActivity' #Point main activity to non Mainactivity

app.sub_activities ='SubActivity' #Include all other files that are needed for app to run

Run the rake command for the app to check if the app compiles, builds, and runs successfully on an emulator or device. To run the application on a device use the device command.

$ rake device

For your application to run successfully on a device, make sure your device settings have permissions provided for the application to run on a device successfully. If you are not sure about the device settings, please follow the instructions below to setup the device.

  • Navigate to the Settings in your Android Device.
  • Scroll down to find System settings (for Google Pixel) or the About Phone section (for all other devices) to open a new screen.
  • Scroll down to find the Build Number item and tap 7 times to enable developer mode.
  • Go back one level or to the previous screen to find the Developer Options and tap on it.
  • Look out for the USB Debugging section and approve your device's request to authorize the Mac/Windows machine used for development.

Now the rake device command should start the app. To understand more about the rake capabilities, you can run the various rake commands. Specifying the app to run on an emulator or a device will need additional settings needed, for the case of simplicity let’s run the application using RubyMotion’s default emulator.

$ rake -T


rake build             # Create an application package file (.apk)


rake clean             # Clear local build objects


rake clean:all         # Clean all build objects


rake config            # Show project config


rake ctags             # Generate ctags


rake default           # Same as 'rake emulator'


rake device            # Build the app then run it in the device


rake device:install    # Install the app in the device


rake device:start      # Start the app's main intent in the device


rake emulator          # Build the app then run it in the emulator


rake emulator:install  # Install the app in the emulator


rake emulator:start    # Start the app's main intent in the emulator


rake release           # Create an application package file (.apk) for release (Google Play)


rake spec              # Same as 'spec:emulator'


rake spec:device       # Run the test/spec suite on the device


rake spec:emulator     # Run the test/spec suite on the emulator

The Android SDK comes with an emulator that can be configured via the command line or Android Studio (if this is your choice of IDE).

Configure Android Emulator Using the Command Line

Follow the steps below to create an Android Emulator or Virtual Device (AVD):

  • Launch the Android command line tool from the terminal, as in ./android which is present inside SDK folder.
  • Click the 'Create' button.
  • Select the option for ABI (x86) and target API and provide a unique name to identify the emulator.
  • Run the emulator to check for a successful run.

Configure Android Emulator Using Android Studio

Follow the steps below to create an Android Emulator or Virtual Device (AVD) using Android Studio.

  • Open the Android Studio application and navigate to the Tools menu to run the AVD Manager option.

  • Click on the Create Virtual Device button to create a new virtual device configurtion.
  • Select the hardware that suits your needs by size and resolution (I picked Pixel 2 XL) and click Next.

  • Select the system image, API Level targets, and download the release if it's not downloaded already.
  • Provide a unique name, orientation, and Advanced settings to complete the setup.

  • Click on Finish and run the emulator.

To run the application on an emulator use the emulator command.

$ rake emulator

Running the rake emulator will compile, create, and auto sign the apk file and open the apk file in an emulator.

Now we have a clearer understanding on RubyMotion, Rakefile, and, of course, our application is off to a great start with an unbeaten run on an Android emulator. Let’s keep the application rolling.

Movie List Creation

RubyMotion did the heavy lifting by generating the needed skeleton for our application. Now, let’s spice up the application by adding a list of movies and linking them to the Wikipedia page.

Create a new file app/movies.rb with Movies class to add an array of movie names.

class Movies
  end

Ruby provides a shortcut to list an array of strings with a %w literal instead of using a traditional array presentation with comma separated double-quoted strings. As an example, the traditional way of writing an array would look like:

movie_names = [“Shrek”, “Frozen”, “Toy Story”, “Finding Nemo”, “Despicable Me”, “Inside Out”]


The movie_names array can be rewritten using the %w literal:

movie_names =

%w(

Shrek

Frozen

Toy\ Story

Finding\ Nemo

Despicable\ Me

Inside\ Out

)

Now, let’s change the shape of the Movies class by adding a list of movies inside the names method.

class Movies
  def self.names
  ##Moviews name list
  	%w(
  		Shrek
        Frozen
        Toy\Story
        FInding\Nemo
        Despicable\Me
        Inside\Out
        Wall-E
        Zootopia
        Brave
        Moana
        Tangled
        Coco
        Ice\Age
        Aladdin
        Rango
        Cars
        Finding\Dory
        Coraline
        Ratatouille
        The\Incredible
        Monsters,\Inc.
  		Kung\Fu\Panda
        Up
        Wolf\Children
        Ponyo
       )
      end
   end

We have the Movie list ready, so let’s create a adapter to access the Movie names from the MainActivity.

Android::Widget::ArrayAdapter.new(self, Android::R::Layout::Simple_list_item_1, Movies.names)

To access and display the Movie list names, the onCreate lifecycle needs to call the list adapter from the onCreate state.

list = Android::Widget::ListView.new(self)

list.adapter = Android::Widget::ArrayAdapter.new(self, Android::R::Layout::Simple_list_item_1, Movies.names)

Loading the movie names on the initial app load works well with ListView and ArrayAdapter using AndroidLayout to choose a list item layout. Now let’s add the click listener event to identify the movie name the user clicked on.

selected_movie = Movies.names[position]

puts "Click event triggered for the movie -> #{selected_movie}"

Passing the parent, view, and position to ItemclickListener will identify the selected movie position and to any intent activity after the click event is triggered. The intent is a message passed between activities, services, broadcast receivers, and content providers, in other words, it is similar to the parameters passed on to an API call asynchronously. In our application, this will make a call to Wikipedia and pass the movie name asynchronously.

intent = Android::Content::Intent.new

Use Android::Context::Intent to create a new intent which can be pointed to a subActivity; let’s name the subactivity wikipediaActivity. Let’s create a new file called wikipedia_activity.rb. 

class WikipediaActivity < Android::App::Activity
end

Specify the file name under the sub_activities section before moving further along inside the rake file

app.sub_activities += %w(WikipediaActivity)

Every Activity created should have an onCreate state similar to the main activity and our goal here is to make the SelectedMovie data pass to the onCreate method and load the Wikipedia link.

movie = self.intent.getStringExtra(SelectedMovie)

wiki_link = "https://en.wikipedia.org/wiki/#{movie}"

puts "Loading #{wiki_link}"

We have the wiki link with the movie name embedded at the end of the link, and in order for our activity to access the internet and load webpages, Android provides a WebView as part of Andorid::Webkit. Add the permission to the rake file specifying the permissions of rake config.

app.permissions = 'android.permission.INTERNET'

Permission is granted to access the webpage, so let’s write logic to load Wikipedia.

webview = Android::Webkit::WebView.new(self)

webview.webViewClient = Android::Webkit::WebViewClient.new

webview.loadUrl wiki_link

self.contentView = webview

Here’s how the onCreate state flow for the wikipedia_activity.rb file should look:

def onCreate(savedInstanceState)
super
movie = self.intent.getStringExtra(SelectedMovie)
wiki_link = "https://en.wikipedia.org/wiki/#{movie}"
webview = Android::Webkit::WebView.new(self)
webview.webViewClient = Android::Webkit::WebViewClient.new
webview.loadUrl wiki_link
self.contentView = webview
end

Accessing the Wikipedia activity from the Main Activity to tie the Movie name link to load the Wikipedia URL is the final step in the process. We'll use the intent mechanism explained above.

intent = Android::Content::Intent.new(self, WikipediaActivity)

intent.putExtra(WikipediaActivity::SelectedMovie, selected_movie)

startActivity(intent)


Let’s rewrite the MainActivity class to have more readability and structure.

class MainActivity < Android::App::Activity
  def onCreate(savedInstanceState)
      super
         list = Android::Widget::ListView.new(self)
     	 list.adapter = Android::Widget::ArrayAdapter.new(self, Android::R::Layout::Simple_list_item_1, Movies.names)
         list.onItemClickListener = self
         list.onItemClickListener = self       
         self.contentView = list
      end
  def onItemClick(parent, view, position, id)
     selected_movie = Movies.names[position]
     intent = Android::Content::Intent.new(self, WikipediaActivity)
     intent.putExtra(WikipediaActivity::SelectedMovie, selected_movie)
     startActivity(intent)
  end
end 

Here’s the link to the working app on GitHub.

Wrapping Up

In this article, we learned RubyMotion by building a Moviepedia app with some Android SDK calls using the power of the Ruby language and the Rake build language. We could have built the app using Android native app or Phone Gap hybrid development; however, once you have a good understanding of Ruby and it’s simplicity to build web apps, RubyMotion feels like an extension to your learning with no or little learning curve.

If you want to dive deeper into RubyMotion Development, check out “RubyMotion Android Development” to understand and see if RubyMotion is right for your Mobile Development needs. Rubymotion might not be a perfect option if you are worried about Memory management or Debugging capabilities. On the brighter side, the Ruby Open community is pretty good in addressing the concerns, thanks to the open source world.

Further Reading

  • RubyMotion Android Development Guide, RubyMotion’s official Android Developer documentation.
  • Android Studio IDE, Android’s official IDE for mobile app development.
  • Understand Android SDK, Android’s SDK for beginner understanding.
  • RubyMotion Support, Community support forums and support ticket.
Android (robot) mobile app

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Streamlining Your Workflow With the Jenkins HTTP Request Plugin: A Guide to Replacing CURL in Scripts
  • The Future of Cloud Engineering Evolves
  • A Simple Union Between .NET Core and Python
  • The Data Leakage Nightmare in AI

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: