Building native Android applications with Mirah and Pindah
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Building native Android applications with Mirah and Pindah

on

  • 9,060 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
9,060
Views on SlideShare
4,677
Embed Views
4,383

Actions

Likes
5
Downloads
77
Comments
0

23 Embeds 4,383

http://blog.zerosum.org 4098
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://morepie 4
http://www.werewolfgame.net 4
http://werewolfgame.net 4
http://feedly.com 3
http://kessy86 3
http://poddb.com 2
http://www.hanrss.com 2
http://www.google.com 1
http://ranksit.com 1
http://www.feedspot.com 1
http://traian658 1
http://translate.googleusercontent.com 1
http://webcache.googleusercontent.com 1
http://offrails.org 1
http://www.google.com.br 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 Presentation Transcript

  • 1. So you want to build Android apps… without Java?
    Nick Plante @zapnap
    (A brief introduction to Mirah and Pindah)
  • 2. Who?
    Nick Plante
    (not a Java developer)
    Zerosum Labs
    Rails Rumble
    Rubydoc.info
    Chinaccelerator
    Contact me!
    @zapnap on Twitter
    http://github.com/zapnap
  • 3. Why?
    Because you’re a Ruby developer (familiarity).
    Because Android is awesome.
    Because simplicity is elegance.
    “Think Different.”
  • 4. 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
  • 5. 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?
  • 6. 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
  • 7. 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
  • 8.
  • 9. 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)
  • 10. One thing at a time
    We’ll get to Android in just a second
    First let’s see some basic Mirah syntax…
  • 11. # 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.
  • 12. .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.
  • 13. .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))));
    }
    }
  • 14. 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
  • 15. 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)
  • 16. 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
  • 17. Now What?
  • 18. 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
  • 19. Android SDK / Virtual Devices
  • 20. The anatomy of a typical Android application
    Activities
    Intents
    Manifest File
    XML Layouts (Views)
    Services
    Content Providers
    (Lots to learn)
  • 21. 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
  • 22. 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
  • 23. 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]
  • 24. 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
    • 25. build.properties
    • 26. local.properties
    • 27. 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...
  • 28. 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);
    }
    }
  • 29. Running the Example App
    $ cdhello_world
    $ rake install
    => WIN.
  • 30. Well, that was boring
  • 31. 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)
  • 32. Up or Down? Down or Up?
  • 33. 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);
    ...
    }
  • 34. 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)
  • 35. 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.
  • 36. 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
  • 37. 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]
  • 38. 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" />
  • 39. It Works!
  • 40. 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
  • 41. 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!
  • 42. 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
    • 43. http://developer.android.com/sdk/index.html
    • 44. http://developer.android.com/guide/developing/projects/projects-cmdline.html