Scala + Android + Eclipse → 書き直しver

昨日書いた内容をブラッシュアップして、誰かの役に立つエントリになるよう頑張る。

http://www.scala-lang.org/node/160

上記を参考に頑張ってみる。
環境はMac OS X 10.6 + Eclipse 3.5
AndroidSDKとADPは既に入ってる状態。

Scalaインストール

僕はMac OS X 10.6 なので、それ以外の環境の人は自分で頑張ってください。

MacPortsScalaを入れる。このエントリ執筆時は scala @2.7.7_0 (active)

sudo port install scala

scala-androidインストール

Scalaにはsbazっていう、CPANとかRubyGems的なものがあるのね... 知らなかった。

sbaz installed

scala-android入ってないか確認。当たり前だけど入ってない。

sbaz available | grep android

で確認。あった。scala-android (2.7.0-final, 2.6.1-final)

sudo sbaz install scala-android

インストールできた。

sbaz installed

確認。OK。

EclipseScalaプラグインインストール

先にScalaプラグインを入れておく。

http://www.scala-lang.org/scala-eclipse-plugin

こっちからプラグイン突っ込んで、面倒くさいけど素のScala使ったプロジェクトがちゃんと動くか確認。

Scala+Androidプロジェクト作成

Eclipse起動して、Androidプロジェクトを作成した。
以下の作業を行う前に、.projectのバックアップを作成しておく。

cp .project .project.bak

Androidプロジェクトを右クリックしてScalaScalaネイチャーの追加する。
プロジェクトのビルダーからJavaビルダーがぽいっちょされてしまう。
とりあえずこの時点で一回起動してみる。Hello World, HelloJava! と表示されるはず。
このままだとどうやらJavaのソースがうまく扱えないっぽいので、さきほどバックアップとっておいた.projectから、Javaビルダーの行を持ってきて復活させておく。

で、プロジェクトのJavaのビルドパスのライブラリータブからScala Library version 2.7.7.finalを除去。外部JARの追加でandroid-library.jarを追加したいんだが場所わからん。色々調べて

port contents scala

で調べたら、自分の場合 /opt/local/share/scala/lib にあった。
参考サイトに書いてある android-library.jarがない...けど、調べてみるとscala-android.jarでいいみたい。

プロジェクトのJavaのビルドパスのライブラリータブにbinフォルダを追加。これをやらないと上手いこと動かない場合があるらしいのでおまじない的に。(GUIからどうやるか分からなかったので直接編集した。)

これでだいたいOKなはずなので、ScalaでActivityとか作ってみる。

package jp.ne.hatena.vvakame

import _root_.android.app.Activity
import _root_.android.content.Intent
import _root_.android.os.Bundle
import _root_.android.view.View
import _root_.android.widget.Button

class HelloScala extends Activity {
  import android.view.View.OnClickListener

  override def onCreate(savedInstanceState: Bundle):Unit = {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.hello_scala)

    findViewById(R.id.changeActivityButton).asInstanceOf[Button]
      .setOnClickListener(()=>{
        startActivity(new Intent(this, classOf[HelloJava]))
      })
  }

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

これもちゃんと動いて、Javaで書いたActivityへ遷移できる。

おまけ

http://github.com/vvakame/HelloScalaForAndroid
↑から、上記の作業が終わった状態の、即動かせる状態のEclipseプロジェクトが入手できるます。
インポートした後に、プロジェクト→クリーン としたほうがいいかも。
ScalaによるActivity→JavaによるActivity→Scal(略 と遷移できます。

.classpath 内の、scala-android.jarのパスを自分の環境用に整えるのを忘れないように。
このエントリ執筆時のリビジョンは 627c138d です。

作成には、以下のサイトを参考にしました。
http://www.ibm.com/developerworks/jp/opensource/library/os-eclipse-scala/

現状の問題点

昨日の問題点はビルダーにJavaビルダーを加えたことでだいぶ解決しました。残りは...

  • apkのサイズでかい。HelloScala.apkが700KBくらいある。別の手元のプロジェクトは画像などのリソース込みで27KBとか。proguardというjarファイルの圧縮,最適化,難読化ツールで不要classを省いたりしてかなり要領圧縮できると聞いたので今度調べる。Scala関係なく恩恵あるはず。