Scala で Android プログラミング

小崎玄顕

平成23年9月1日(木)

自己紹介

なぜ Scala なのか!?

簡潔に…

before (Java)

        Button button = (Button)findViewById(R.id.Button01);
        button.setOnClickListner(new OnClickListener {
          public void OnClick(View v) {
             // むにゃむにゃ
          }
        });
      

after (Scala)

        findView(TR.Button01).setOnClickListener( () => {
          // むにゃむにゃ
        })
      

あら素敵。キャストが不要なのね。

簡潔に…

before (Java)

        public static void useAlarms() {
          Cursor cur = getAlarmsCursor();
          if (cur.moveToFirst()) {
            do {
              Alarm alarm = new Alarm(cur);
              // ほげほげ
            } while (cur.moveToNext());
          }
          cur.close();
        }
      

after (Scala)

        def useAlarms() { using(getAlarmsCursor()) { c =>
            c.map(new Alarm(_)).foreach(alarm => {
               // ほげほげ
            })
        } }
      

あら素敵。リソースを自動的に開放してくれるのね。

だんだん使ってみたくなってきましたね。

導入方法

前提

導入方法

段取り

  1. Android SDK の導入
  2. AVD(Android Virtual Device)の作成
  3. sbt(Simple Build Tool)の導入
  4. conscript の導入
  5. giter8 の導入
  6. template の作成
  7. エミュレータ実行
  8. 実機で実行

1. Android SDK の導入

android sdk でググって下さい。

…あまりに不親切か

この辺

android-sdk_r12-linux_x86.tgz をダウンロード

適当な場所に解凍(例 : ~/android-sdk-linx_x86/ とか)

解凍した場所を $ANDROID_HOME とし、 $ANDROID_HOME/tools, $ANDROID_HOME/platform-tools に PATH を通しておくといいよ

1. Android SDK の導入

以上で導入終わりかと言うとそんなことは全然ない

本当の SDK 導入はこれからだ!

$ANDROID_HOME/tools/android を起動して下さい

Available packages から必要なファイルを選択してインストール

Xperia の人は SDK Platform 2.1 を、Galaxy S II の人は 2.3 を、 といった風に適当にそれっぽい SDK を選ぶ。

2. AVD (Android Virtual Device) の作成

まだ AVD マネージャーを起動していますか?終了してしまった人はもう一度起動。

次にテストに必要となるエミュレータを用意します

AVD マネージャーのメニューで Virtual devices を選ぶと、まだ何もないのでここに作ります

いくつでも作れるけど、とりあえず 1コだけ作れば確認はできる

オプションとかわかんねぇから適当で、後で困ったら考える

「Start...」ボタンでエミュレータが起動したらとりあえず成功

3. sbt(Simple Build Tool)の導入

やっと Scala の導入です

ここでは sbt というツールと共にインストールする方法を紹介します

まずは ここから sbt-launch-0.7.7.jar をダウンロード

んで、起動スクリプトを書いて PATH の通った所に置く。wiki に書いてあるまんま

          java -Xmx1536M -Xss1M -XX:MaxPermSize=256m \
               -XX:+CMSClassUnloadingEnabled \
               -jar `dirname $0`/sbt-launch-0.7.7.jar "$@"
        

CMSClassUnloadingEnabled とか MaxPermSize とか指定しとかないと落ちるよ

sbt の最新バージョンは 0.10.0 ですが、続いて紹介する android_plugin がうまく動かなかったので、 ここでは一つ前のバージョン 0.7.7 を使用します。

3. sbt(Simple Build Tool)の導入

稼動確認を兼ねた超入門

ホームディレクトリにプロジェクト用のディレクトリを作成しましょう。例えば hello

        $ mkdir hello
        $ cd hello
      

ここで sbt を実行

        $ sbt
        Project does not exist, create new project? (y/N/s)
      

て聞かれるから、y と答える

        Name: hello
        Organization: com.sample.kokou
        Version [1.0]:
        Scala version [2.9.0]: 2.9.1
        sbt version [0.7.7]:
      

て適当に答える

Scala は最近 2.9.1 がリリースされたよ。

sbt のバージョンはそのままにしておいて下さい。

Getting net.java.dev.jna jna 3.2.3 ...
:: retrieving :: org.scala-tools.sbt#boot-app
	confs: [default]
(中略)
[success] Successfully initialized directory structure.
Getting Scala 2.9.1 ...
downloading http://repo1.maven.org/maven2/org/scala-lang/scala-compiler/2.9.
	[SUCCESSFUL ] org.scala-lang#scala-compiler;2.9.1!scala-compiler.jar
downloading http://repo1.maven.org/maven2/org/scala-lang/scala-library/2.9.1
	[SUCCESSFUL ] org.scala-lang#scala-library;2.9.1!scala-library.jar (
downloading http://repo1.maven.org/maven2/org/scala-lang/jline/2.9.1/jline-2
	[SUCCESSFUL ] org.scala-lang#jline;2.9.1!jline.jar (379ms)
:: retrieving :: org.scala-tools.sbt#boot-scala
	confs: [default]
	4 artifacts copied, 0 already retrieved (19939kB/40ms)
[info] Building project hello 1.0 against Scala 2.9.1
[info]    using sbt.DefaultProject with sbt 0.7.7 and Scala 2.7.7
      

…できた

とりあえず hello world

hello/src/main/scala というディレクトリが作られてるから、そこに hello.scala 作成

          object Hello { 
            def main(args: Array[String]) { 
              println("hello world")
            }
          }
        

雰囲気わかるよね

sbt でプロジェクトを作成した直後の状態であれば素気ないプロンプトが表示されてるはず

        > compile
        (中略)
[info] == compile ==
[success] Successful.
[info] 
[info] Total time: 12 s, completed 2011/09/02 0:37:48
      

んで実行

        > run
        (中略)
[info] == run ==
[info] Running Hello 
hello world
[info] == run ==
[success] Successful.
[info] 
[info] Total time: 0 s, completed 2011/09/02 0:39:10
      

確認終わり

4. conscriptの導入

Conscript とは何か?

この次に導入する giter8 のために必要なだけなので気にしない ┐(´д`)┌

4. conscriptの導入

インストール方法

ここから conscript-0.3.1.jar を入手

んで実行

          $ java -jar conscript-0.3.1.jar
        

すると、~/bin/cs が勝手にインストールされます。 インストール先の変更方法はわかりません。

          $ cs --version
Usage: cs [options] [/[/]]

  --clean-boot
        clears boot dir
  --setup
        installs sbt launcher
  -b  | --branch 
        github branch (default: master)
  --version
        print current version
  [/[/]]
        github project
        

5. giter8の導入

giter8 とは

github に色んな人が sbt プロジェクトのサンプルを公開しています。

中には giter8 用に公開してくれている人もいて、 これを我々は拝借することで初回導入のハードルを下げることができるのです。

5. giter8の導入

インストール方法

          $ cs n8han/giter8
        

以上!

6. Template の作成

giter8 の動作確認も兼ねて

まずは利用可能なテンプレートを確認する

          $ g8 --list | grep android
charroch/android                        
gseitz/android-sbt-project              A g8 template project for android de
velopment
        

gseitz/android-sbt-project が求めていたテンプレートです

android-pluginのサイトに jberkel/android-app がテンプレートとして紹介されているけど、うまく行きませんでした。

6. Template の作成

テンプレートを元にプロジェクトを作成

          $ g8 gseitz/android-sbt-project
Creates an Android SBT  project. 

platform [4]: 7
package [my.android.project]: 
name [My Android Project]: Hello

Applied gseitz/android-sbt-project.g8 in hello
        

6. Template の作成

          $ cd hello
          $ less src/main/scala/Activity.scala
package my.android.project

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

class MainActivity extends Activity {
  override def onCreate(savedInstanceState: Bundle) {
    super.onCreate(savedInstanceState)
    setContentView(new TextView(this) {
      setText("hello, world")
    })
  }
}
        

テンプレートだから、もう hello world ができてる

7. エミュレータ実行

じゃあコンパイル

$ sbt
(中略)
[info] Building project Hello 0.1 against Scala 2.8.1
[info]    using Parent with sbt 0.7.4 and Scala 2.7.7
> compile
(中略)
[success] Successful.
[info] 
[info] Total time: 10 s, completed 2011/09/02 22:32:48
        

7. エミュレータ実行

最初の辺で作成した AVD を起動

$ $ANDROID_HOME/tools/emulator -avd Xperia &
        

sbt 上で start-emulator したら起動しそうな気がしたけどダメだった。

エミュレータにインストール

$ sbt
> install-emulator
(いろいろエラーが出るけど気にしない)
[info] == Hello / install-emulator ==
[info] == Hello / install-emulator ==
[success] Successful.
[info] 
[info] Total time: 7 s, completed 2011/09/02 22:42:39
        

エミュレータのメニューに Hello が追加されていれば成功です

8. 実機で実行

もちろん Android 機、持ってますね

この辺のガイドに従って、udev のルールを追加して下さい。(Ubuntu 前提であることを今、思い出した)

Xperia の人は /etc/udev/rules.d/51-android.rules をこんな感じで作成

SUBSYSTEM=="usb", ATTR{idVendor}=="0fce", MODE="0666", GROUP="plugdev" 
        

Xperia でない人は "0fce"の辺を適当に変更して下さい。

USBケーブルで Android 機を PC に接続、USBデバッグモード&提供元不明のアプリのインストールを許可しておきます

$ $ANDROID_HOME/platform-tools/adb devices
List of devices attached 
CB511K8F6D	device
        

な風で認識できていることを確認

8. 実機で実行

実機にインストール

$ sbt
(中略)
> install-device
(やっぱり色々エラーが出るけど無視)
[info] == Hello / install-device ==
[info] == Hello / install-device ==
[success] Successful.
[info] 
[info] Total time: 9 s, completed 2011/09/02 23:06:21
        

インストールできましたか?

おつかれさまでした