[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
SlideShare a Scribd company logo
Scalaで
Androidアプリ開発
  papamitra / ScalaZa01
自己紹介
●   Twitter ID: papamitra
●   Web: http://d.hatena.ne.jp/papamitra/
●   名古屋Scala勉強会/第7回から参加
●   Scala歴: 6ヶ月
●   Android歴: 7ヶ月
●   Java歴: ほぼなし
最初は別の言語で開発していたが…

   とあるLispのJVM言語
途中でScalaに乗り換えた
Scalaで開発するメリットって?
Androidアプリが動くまで
     ソースコード
          ↓
    .classファイル
          ↓
     .dexファイル
          ↓
     .apkファイル
          ↓
   インストール、実行
メソッド名を間違えた
    (動的言語の場合)

    インストールまで完了して
        いざ、実行
          ↓

NoSuchMethodException
      (そんなメソッドないよ)
メソッド名を間違えた
         (Scalaの場合)

         コンパイラが指摘
 /src/main/scala/CameraService.scala:47: value comprress is not a
member of android.graphics.Bitmap
        bitmap.comprress(Bitmap.CompressFormat.JPEG, 90, outStream)
               ^
 one error found
Scalaならコンパイラが強力に
        エラーチェック
  ソースコード
       ↓    ←Scalaはここで多くのエラーを補足
 .classファイル
       ↓
  .dexファイル
       ↓
  .apkファイル
       ↓
インストール、実行 ←ここで例外が起きるのは悲しい
Scalaなら
実行時エラーが少なくて済む!
型チェックなら
  Javaにもあるけど…


Scalaならコードが
 簡潔に書ける!
Javaのコード例
           (OnClickListener)


Button button = (Button)findViewById(R.id.Button01);
button.setOnClickListener(new OnClickListener{
        public void OnClick(View v){
           // クリック処理
        }
})
Scalaのコード例
          (OnClickListener)

findView(TR.Button01).setOnClickListener( () => {
    // クリック処理
})




     こんなに簡単に!
Scalaのコード例
                 (OnClickListener)

                        暗黙の型変換を使用

implicit def funcToClicker0(f:() => Unit): OnClickListener() {def onClick(v:View):Unit=f.apply}




  http://www.ibm.com/developerworks/jp/opensource/library/os-eclipse-scala/
Javaのコード例
            (Cursor)
public static void useAlarms() {
   Cursor cur = getAlarmsCursor();
   if (cur.moveToFirst()) {
      do{
         Alarm alarm = new Alarm(cur);
         // alarmを使うコード
      }while(cur.moveToNext());
   }
   cur.close();
}
Scalaのコード例
             (Cursor)


def useAlarms(){ using(getAlarmsCursor()){c=>
  c.map(new Alarm(_)).foreach(alarm=>{
    // alarmを使ったコード
  })}}
Scalaのコード例
                   (Cursor)

def using[A <: {def close(): Unit}, B](param:A)(f: A=>B):B=
  try{
    f(param)
  }finally{
    param.close()
  }
                 『Scalaプログラミング入門』より
Scalaのコード例
             (Cursor)


def useAlarms(){ using(getAlarmsCursor()){c=>
  c.map(new Alarm(_)).foreach(alarm=>{
    // alarmを使ったコード
  })}}
Scalaのコード例
               (Cursor)
private object EmptyCursorIter extends Iterator[Cursor]{
  def hasNext = false
  def next:Cursor = throw new java.util.NoSuchElementException()
}

private class CursorIter(cur: Cursor) extends Iterator[Cursor]{
  def hasNext = !cur.isLast()
  def next:Cursor =
    if (cur.moveToNext) cur
    else
      throw new java.util.NoSuchElementException()
}

implicit def cursor2Iterator(cur: Cursor): Iterator[Cursor] =
  if(!cur.moveToFirst) EmptyCursorIter
  else{
    cur.moveToPrevious
    new CursorIter(cur)
  }
Scalaなら簡潔で
わかり易いコードが書ける!
その一方
Javaっぽく書くこともできる
JavaのHelloアプリ
package org.example.hello;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class HelloAndroid extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView tv = new TextView(this);
        tv.setText("Hello,Android");
        setContentView(tv);
    }
}
ScalaのHelloアプリ
package org.example.helloscala

import android.app.Activity
import android.os.Bundle
import android.widget.TextView

class HelloAndroid extends Activity {
  override def onCreate(savedInstanceState: Bundle) {
    super.onCreate(savedInstanceState)
    val tv = new TextView(this)
    tv.setText("Hello Android, it's me, Scala!")
    setContentView(tv)
  }
}
ちなみにClojureのHelloアプリ

(ns org.example.hello.HelloAndroid
  (:gen-class
   :extends android.app.Activity
   :exposes-methods {onCreate superOnCreate}))

(defn -onCreate [this #^android.os.Bundle bundle]
  (.superOnCreate this bundle)
  (let [tv (new android.widget.TextView this)]
    (.setText tv "Hello Android from Clojure!")
    (.setContentView this tv)))
Scalaで開発するメリット
             まとめ
●   とりあえずJavaっぽく書いて動かせるので
    AndroidとScala、両方初心者でも安心

●   Scalaに慣れてくればその機能でわかり易く
    簡潔なコードが記述可能

●   しかもコンパイラの強力な型チェックで
    実行時のエラーを低減
デメリットはないの?
アプリサイズが大きく…
               コードサイズ   apkサイズ


 Hello,World     -      13KB
                                 Proguardを使っているものの…
  1画面                            同機能のJava実装と
 1サービス          24KB    111KB    比較して4〜5倍(主観)
1ウィジェット


                82KB    215KB
  3画面
 2サービス




Android2.2からはSDカードにアプリをインストールできる
→それほど気にならなくなる?
protected staticにアクセス不可
                       Scalaの仕様で
    protected staticクラス/メソッド/フィールドにアクセス不可




   Androidでは
   com.google.android.maps.ItemizedOverlay
   を継承して使うときに問題が…




現状Javaでラッパを書くしか手がない?
→ItemizedOverlayにはラッパがあります
 http://github.com/brianhsu/ScalaMap
Google Maps API(maps.jar)
     使用でコンパイルエラー
     error: error while loading MapView, Missing dependency
        'class android.view.ViewGroup$LayoutParams'




                                            android.jar,maps.jarはいずれも
                                            実装が全て例外スローに
                                            置き換えられたスタブ




Rev22630にてコンパイルできるように修正されたようです
次期バージョン(2.8.1?)に期待
Google Maps API(maps.jar)
         でコンパイルエラー


Q.   2.8.0以前のバージョンではどうすればよい?


A.   maps.jarを改変して回避する力技を公開しています
http://d.hatena.ne.jp/papamitra/20100627/scala_maps
Scalaで開発するデメリット
        まとめ




いろいろあるけどなんとかなるよ!
Let's Scala + Android !
おまけ


もうちょっとだけ続くんじゃ
私のAndroid開発環境
●   sbt + sbt-android-plugin
    Scala製ビルドツール
●   ensime
    emacs上のScala開発環境
●   Eclipse + Abdroid-plugin
    xml編集するのに使用
sbt-android-plugin
●    Apk作成はもちろん実機/エミューレータへのイ
     ンストールも面倒見てくれる
●    proguardも勝手にかけてくれる
●    インストールはファイル1つDLして
     パス通すだけ
    http://github.com/jberkel/android-plugin/raw/master/script/create_project
sbt-android-plugin
サンプルプロジェクトを作成して実機にインストールするまで

$ create_project HelloAndroid org.papamitra.helloandroid 
  --platform android-2.1 --scala-version 2.8.0 
  --activity HelloAndroid
$ cd HelloAndroid
$ sbt update
$ sbt install-device
sbt-android-plugin
               型付きリソース参照も装備!


val button = findViewById(R.id.button).asInstanceOf[Button]




              val button = findView(TR.button)
ensime
●   Emacs上のScala開発環境
●   補完してくれたり
●   クラスの詳細を表示したり
●   Flymakeっぽいこともしてくれる
●   http://github.com/aemoncannon/ensime
ensime
●   補完
ensime
●   クラス詳細
ensime
●   flymake
まとめ
まとめ




ご自分に合ったツールをお使いください
おわり

More Related Content

ScalaでAndroidアプリ開発

Editor's Notes

  1. 40秒
  2. 50秒
  3. 20秒