• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Building native Android applications with Mirah and Pindah
 

Building native Android applications with Mirah and Pindah

on

  • 8,692 views

So you want to build native Android applications without using Java? Here's how.

So you want to build native Android applications without using Java? Here's how.

Statistics

Views

Total Views
8,692
Views on SlideShare
4,428
Embed Views
4,264

Actions

Likes
5
Downloads
75
Comments
0

22 Embeds 4,264

http://blog.zerosum.org 3980
http://wiki.nhruby.org 148
http://feeds.feedburner.com 35
http://www.offrails.com 22
http://localhost 21
http://kestal 14
http://kris81 8
http://www.verious.com 7
http://werewolfgame.net 4
http://morepie 4
http://www.werewolfgame.net 4
http://feedly.com 3
http://kessy86 3
http://www.hanrss.com 2
http://poddb.com 2
http://translate.googleusercontent.com 1
http://traian658 1
http://offrails.org 1
http://www.feedspot.com 1
http://ranksit.com 1
http://www.google.com 1
http://webcache.googleusercontent.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Building native Android applications with Mirah and Pindah Building native Android applications with Mirah and Pindah Presentation Transcript

    • So you want to build Android apps… without Java?
      Nick Plante @zapnap
      (A brief introduction to Mirah and Pindah)
    • Who?
      Nick Plante
      (not a Java developer)
      Zerosum Labs
      Rails Rumble
      Rubydoc.info
      Chinaccelerator
      Contact me!
      @zapnap on Twitter
      http://github.com/zapnap
    • Why?
      Because you’re a Ruby developer (familiarity).
      Because Android is awesome.
      Because simplicity is elegance.
      “Think Different.”
    • Java vs Ruby
      Dynamic vs Static
      Simplicity vs Complexity & Verbosity
      Less Ceremony
      Java is a systems programming language, after all
      But… The JVM is an awesome platform
      Android’s use of the JVM (Dalvik) gives us options
    • Java Alternatives
      Android Scripting Environment (SL4A)
      Great for scripting; not great for applications
      Limited access to Android API / GUI
      Performance issues
      Other JVM-based languages:
      Scala
      Clojure
      JRuby
      Mirah
      Groovy?
    • JRuby & MrRuboto
      Ruboto is your friend!
      JRuby interface / framework for Android APIs
      http://ruboto.org
      But JRuby runtime overhead is a problem
      Slow startup (~10 seconds)
      Large APK size
      HelloWorld: 3.4MB compressed, 10MB installed
    • Introducing Mirah
      Mirah compiles straight to Java bytecode
      Very fast, no extra overhead
      Syntax is very Ruby-ish
      Statically-typed with local type inference
      “Ruby with type annotations”
      No runtime library
      Mix and match Java code
    • Warning!
      Mirah is still a very young language (v0.0.7)
      Tooling is very, very alpha
      Advantage: Eclipse (Java)
      Redcar looks promising
      Compilation errors are very, very not-so-fun
      NativeException: jmeta.SyntaxError: expected Ensure before ' { |a b| Inte' (at line: 16, char: 40)
    • One thing at a time
      We’ll get to Android in just a second
      First let’s see some basic Mirah syntax…
    • # fib.mirah
      def fib(a:int):int
      if a < 2
      a
      else
      fib(a-1) + fib(a-2)
      end
      end
      puts fib(20)
      Ruby vsMirah
      Parameter type declaration???
      SRSLY? 
      # fib.ruby
      def fib(a)
      if a < 2
      a
      else
      fib(a-1) + fib(a-2)
      end
      end
      puts fib(20)
      Return type can often be inferred.
    • .class output
      Produces a java .class
      $ mirahcfib.mirah
      public static intfib(int)
      Can also produce .java code
      $ mirahc -jfib.mirah
      * I have no idea why you would want to do this.
    • .to_java => “ick”
      // Generated from hello.mirah
      public class Hello extends java.lang.Object {
      public static void main(java.lang.String[] argv) {
      java.io.PrintStream temp$1 = java.lang.System.out;
      temp$1.println(Hello.fib(20));
      }
      public static intfib(int a) {
      return (a < 2) ? (a) : ((Hello.fib((a - 1)) + Hello.fib((a - 2))));
      }
      }
    • Challenges / Major Differences
      Java stdlib: both a blessing and a curse
      List, HashMap, etc
      arr.get(1) vs arr[0]
      Blocks work, but syntactic sugar required
      For example, List#eachcan be used (array)
      But HashMap#eachdoes not exist
      No optional arguments, no *splats, no ranges
    • Using Java’s Standard Library
      import java.util.Collections
      import java.util.HashMap
      import java.util.List
      class ListPrinter
      def print(list:List)
      puts "first item: #{list.get(0)}"
      list.each do |item|
      puts "item: #{item}"
      end
      end
      end
      class HashPrinter
      def print(map:HashMap)
      map.keySet.each do |key|
      puts "#{key}: #{map.get(key)}"
      end
      end
      end
      map = { 'batman' => 'brucewayne', 'superman' => 'clarkkent' }
      HashPrinter.new.print(map)
      list = ['peter', 'stewie', 'brian']
      ListPrinter.new.print(list)
    • Get Mirah
      # Install JRuby 1.6 if you haven’t already
      # (or rvm use jruby)
      $ jruby –S gem install mirah
      $ mirah-e "puts 'hello world'”
      > hello world
    • Now What?
    • Get the Android SDK
      Download and install it:
      http://developer.android.com/sdk/index.html
      Notes on building from the command line:
      http://developer.android.com/guide/developing/projects/projects-cmdline.html
      Set up your environment (see above):
      Make sure to set JAVA_HOME, CLASSPATH, and put your platform-tools directory in your path
    • Android SDK / Virtual Devices
    • The anatomy of a typical Android application
      Activities
      Intents
      Manifest File
      XML Layouts (Views)
      Services
      Content Providers
      (Lots to learn)
    • Hello Pindah
      Garrett, Protoform, Mirahndroid => Pindah
      Goals
      Make it easy to get started with Android + Mirah
      Make day to day development tasks easier
      Provide project structure and conventions
      Application skeleton generator
      Rake tasks to hide Ant nastiness
      Because XML is pain
      Use Rake to compile / debug / install / etc
    • What Pindah Does NOT Do
      No “pretty” wrappers for Android APIs
      You must learn the APIs to work effectively
      Does not provide alternatives to XML-based Manifest or view layouts
      https://github.com/objo/droid-views
    • Get Pindah
      # For more information, see
      # http://github.com/mirah/pindah
      $ jruby –S gem installpindah
      # Generate an Android application skeleton
      $pindahcreate org.example.hello [/path/to/hello_world] [HelloActivity]
    • Android App Skeleton
      ├── AndroidManifest.xml
      ├── Rakefile
      ├── libs
      ├── res
      │   ├── drawable-hdpi
      │   │   └── ic_launcher.png
      │   ├── drawable-ldpi
      │   │   └── ic_launcher.png
      │   ├── drawable-mdpi
      │   │   └── ic_launcher.png
      │   ├── layout
      │   │   └── main.xml
      │   └── values
      │   └── strings.xml
      └── src
      └── org
      └── example
      └── hello
      └── HelloActivity.mirah
      Managed for you by Pindah:
      • default.properties
      • build.properties
      • local.properties
      • build.xml
    • Pindah Rake Tasks
      $ rake -T
      Android SDK Tools Revision 8
      Project Target: Android 2.1-update1
      API level: 7
      ------------------
      Resolving library dependencies:
      No library dependencies.
      ------------------
      Importing rules file: tools/ant/main_rules.xml
      rake clean # Removes output files created by other targets.
      rake compile # Compiles project's .mirah files into .class files
      rake debug # Builds the application and signs it with a debug key.
      rake install # Installs/reinstalls the debug package onto a running ...
      rake javac # Compiles R.java and other gen/ files.
      rake logcat # Tail logs from a device or a device or emulator
      rake release # Builds the application.
      rake spec # Print the project spec
      rake uninstall # Uninstalls the application from a running emulator or dev...
    • Android Activity Boilerplate
      # HelloActivity.mirah
      package org.example.hello
      import android.app.Activity
      class HelloActivity < Activity
      def onCreate(state)
      super state
      setContentViewR.layout.main
      end
      end
      # HelloActivity.java
      package org.example.hello;
      import android.app.Activity;
      public class HelloActivity
      extends Activity
      {
      /** Called when the activity is first created. */
      @Override
      public void onCreate(
      Bundle savedInstanceState)
      {
      super.onCreate(
      savedInstanceState);
      setContentView(
      R.layout.main);
      }
      }
    • Running the Example App
      $ cdhello_world
      $ rake install
      => WIN.
    • Well, that was boring
    • Slightly More Interesting
      More expressive code == visible improvement
      Example application
      “Up or Down?” website testing app
      http://github.com/zapnap/upordown
      Questions:
      What do Android callbacks look like?
      How do I leverage 3rd party (Java) libraries?
      How do I handle exceptions?
      How does Mirah deal with scope? (it’s weird)
    • Up or Down? Down or Up?
    • Android Listeners (Java)
      // Sample button click listener in Java
      // Create an anonymous implementation of OnClickListener
      private OnClickListenermClickListener = new OnClickListener() {
      public void onClick(Viewv) {
      // handle click event
      }
      };
      protected void onCreate(BundlesavedValues) {
      ...
      // Capture our button from layout
      Button mSubmit = (Button)findViewById(R.id.submit_btn);
      // Register the onClick listener with theimpl above
      mSubmit.setOnClickListener(mClickListener);
      ...
      }
    • StatusActivity + Listeners
      class StatusActivity < Activity
      def onCreate(state)
      super state
      setContentViewR.layout.main
      @url = EditTextfindViewById(R.id.url_txt)
      @submit = Button findViewById(R.id.submit_btn)
      setListeners
      end
      def setListeners
      this = self
      # SHORTCUT: click listener must implement onClick
      @submit.setOnClickListener do |v|
      status = this.checkSiteStatus(this.getUrl)
      this.showResult status
      end
      end
      Scoping for ivars and self is incomplete. Assign a local var within scope.
      Easy to add anonymous listeners with this syntax (implements a single method interface)
    • Using External Java Libraries
      Put jars in libs folder and import to use. Simple! (must import Android libs too)
      import java.net.URL
      import java.net.SocketTimeoutException
      import org.jsoup.Jsoup
      import org.jsoup.nodes.Document
      def checkSiteStatus(address:String):String
      return "Please specify a URL to test" if address.equals('')
      begin
      doc = Jsoup.connect(
      "http://downforeveryoneorjustme.com/" + address
      ).get
      res = doc.select("#container").first.text
      Log.d 'StatusActivity',
      'Full response from server is: ' + res
      res.substring(0, res.indexOf('Check another'))
      rescue SocketTimeoutException => ex
      "Unable to contact the server. How ironic!”
      end
      end
      Exception handling works like it does in Ruby. Must import specific exceptions.
    • Wrapping Up: Dialog Example
      def getUrl
      @url.getText.toString
      end
      def showResult(message:String)
      alert = AlertDialog.Builder.new(self)
      alert.setTitle 'Site Test Results’
      alert.setMessage message
      alert.setPositiveButton('OK') do |dialog, w|
      dialog.dismiss
      end
      alert.show
      end
    • Android XML Layouts (main.xml)
      <?xml version="1.0" encoding="utf-8"?>
      <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="vertical"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent">
      <LinearLayout
      android:orientation="vertical"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content">
      <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:gravity="center_horizontal"
      android:textSize="20sp"
      android:textStyle="bold"
      android:text="@string/app_title" />
      <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:gravity="center_horizontal"
      android:textSize="18sp"
      android:textStyle="bold"
      android:layout_marginBottom="10dip"
      android:text="@string/app_subtitle" />
      <EditTextandroid:id="@+id/url_txt"
      android:layout_width="fill_parent"
      android:singleLine = "true"
      android:layout_height="wrap_content"
      android:inputType="textUri"
      android:hint="@string/url_example" />
      <Button android:id="@+id/submit_btn"
      android:layout_width="140dip"
      android:layout_marginTop="6dip"
      android:layout_height="wrap_content"
      android:layout_gravity="center"
      android:gravity="center"
      android:text="@string/submit_btn" />
      </LinearLayout>
      <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:gravity="center_horizontal"
      android:layout_alignParentBottom="true"
      android:autoLink="web"
      android:text="@string/powered_by" />
      </RelativeLayout>
      <EditTextandroid:id="@+id/url_txt"
      android:layout_width="fill_parent"
      android:singleLine = "true"
      android:layout_height="wrap_content"
      android:inputType="textUri"
      android:hint="@string/url_example" />
      more info
      app title
      [ url input ]
      [ button]
    • One More Thing
      Android Manifest lists top-level activities and required permissions
      Our app requires Internet access
      Add the permission to AndroidManifest.xml:
      <uses-permission android:name="android.permission.INTERNET" />
    • It Works!
    • Ideas for Next Steps
      Implement a ProgressDialog
      And perform the site check in an AsyncTask
      Record a log of website test history to a ListView
      Allow users to browse test history through a separate Activity
      Store test history to a local Sqlite database (and ListAdapter)
      Fork me at
      http://github.com/zapnap/upordown
    • Conclusions (or lack thereof)
      Mirah is a nice midpoint between Ruby and Java
      Well-suited for Dalvik JVM work
      But still very immature / not yet practical for daily use
      Opportunity to help push mobile dev forward
      Lack of good IDE support
      Makes working with the (massive) Android API difficult
      Debugging is a pain in the butt
      ADB (Rake logcat) is incredibly useful; learn to use it
      I personally still prefer mobile web development ;-) but sometimes native is the way to go!
    • And so it goes
      Mirah Language Resources
      http://mirah.org
      http://github.com/mirah/mirah
      Pindah and Mirah and Android Oh My!
      http://github.com/mirah/pindah
      http://github.com/technomancy/garrett (experiments)
      http://threebrothers.org/brendan (urbanspoon)
      • General Android Development
      • http://developer.android.com/sdk/index.html
      • http://developer.android.com/guide/developing/projects/projects-cmdline.html