Hatena::ブログ(Diary)

papamitra RSSフィード

2010-07-19

[][][]sbt-android-pluginで型安全にリソース取得

ネタ元はここ

http://code.technically.us/post/824974287/rewiring-android-for-type-safe-layout-resources

sbt-android-pluginが0.5.0からTyped resources referencesという便利なものに対応したので紹介。

短く型安全なリソース取得

Scalaでボタンなどのリソースをとってくるのにはいちいち

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

こんな感じに書かないといけない。さすがにこれは長いのでimplicit conversionを使って短く書く方法をここでも紹介した。

この以前紹介した方法は、単に短く書けるというだけで型安全ではなかった。上のコードでいうと本当にButtonオブジェクトへの参照が取得できるかどうかは実行時じゃないとわからなかった。


sbt-android-pluginが0.5.0から提供する機能はこのリソース取得を短く書けて、さらに型安全も提供するすぐれものだ。

この機能を使うと上のコードは

val button = findView(TR.button)

と書けるようになる。しかもButton型の指定がなくてもちゃんとButton型のオブジェクトを返してくれる。


仕組みに関してはネタ元のページに書いてある。簡単に説明すると、ビルド時にリソースファイル(res/layout/*.xml)から型とidを対応つけたTR.scalaというファイルを生成して、それを使ってリソースの取得をおこなう。

ちなみに生成されるTR.scalaはこんな感じ。

case class TypedResource[T](id: Int)
object TR {
  val mapview = TypedResource[com.google.android.maps.MapView](R.id.mapview)
  val list = TypedResource[android.widget.ListView](R.id.list)
  val button = TypedResource[android.widget.Button](R.id.button)
}
// 以下略

使用方法

プロジェクトファイル(project/build/<プロジェクト名>.scala)のMainProjectにTypedResourcesトレイトをmix-in

class MainProject(info: ProjectInfo) extends AndroidProject(info) with Defaults with MarketPublish with TypedResources{
  //...
}

あとはアクティビティクラスにTypedActivityトレイトをmix-inしてやればfindViewが使えるようになる。

Viewに対してfindViewが使いたい場合はimport TypedResources._してやればよい。

2010-07-06

[][][]sbtでScala+Android その2

前回に引き続きsbt+Android。いろいろ触ってみて困った点など3点ほど。


minSdkVersionがないとコンパイルエラー

AndroidManifest.xmlにminSdkVersionがないと警告ではなく、なぜかいきなりjava.util.NoSuchElementExceptionが投げられるスパルタ仕様。

以下をAndroidManifest.xmlに追加すればよい。("7"はAndroid-2.1の場合)

<uses-sdk android:minSdkVersion="7"></uses-sdk>

create_projectで作った場合はデフォルトで記載されているようだ。


外部ライブラリの使用

外部のライブラリjarを使用したい場合は、プロジェクト直下にlibディレクトリを作ってそこにjarを置いてやればOK。

前回の例だとHelloAndroid/libというディレクトリを作ればよい。


これはAndroid-Pluginというよりsbtで外部ライブラリを使うための標準の方法のようだ。


maps.jarにパスが通らない

どうもmaps.jarがおいてあるパスの指定がデフォルトだと正しくないので上書きしてやる必要がある。

前回の例だとproject/build/HelloAndroid.scalaclass MainProjectに以下を追加。

override def addonsPath = androidSdkPath / "add-ons" / "google_apis-7_r01" / "libs"

google_apis以下は使用しているバージョンに合わせる。(上の例はAndroid-2.1)


ただしScala+maps.jarコンパイラが依存関係の解決に失敗するので対策が必要。詳しくは以前の記事参照。

Scala+AndroidでGoogle Mapsがコンパイルエラーになる(解決編?)

2010-07-02

[][][][]sbtでScala+Android

以前紹介したScala+Androidのスライドにあったsbt+Androidを試してみたけど、これは良い!

セットアップは簡単だし、その上一度セットアップしてしまえば、あとは1コマンドでsbt+Androidなプロジェクトが作れてしまう。


ところでsbtって?

sbt(simple-build-tool)Scala製のビルドツール。Scalaは当然のことながらJavaビルドにも対応している。

プラグインによる機能拡張にも対応していて、今回はその機能拡張の1つであるAndroid-Pluginを使用する。


sbtについてはここらへんを見れば概要がわかるはず。

http://blog.8-p.info/2010/4-sbt-scala

http://d.hatena.ne.jp/yojik/20100328/1269770903


sbtセットアップ

http://code.google.com/p/simple-build-tool/wiki/Setup ここにある通りやれば問題ない。

  1. パスの通ったディレクトリsbt-launch.jarをコピーする
  2. 同じディレクトリにsbtというファイルを作る。中身はこう
    java -Xmx512M -jar `dirname $0`/sbt-launch.jar "$@"
    
  3. sbtに実行属性をつけておく
    $ chmod u+x ./sbt
    

sbt-androidセットアップ

以下のコマンドでOK

$ git clone http://github.com/jberkel/android-plugin.git
$ cd sbt-android
$ sbt publish-local

追記(2010/07/19):上記セットアップは不要だった。下にあるcreate_projectさえあればsbt-android-plugin.jarは勝手にダウンロードしてきてくれる。


あとはandroidプロジェクト作成スクリプトcreate_projectをパスの通ったディレクトリにダウンロードして実行属性をつけておく。


androidプロジェクトの作成とビルド

冒頭でも書いたとおりプロジェクトの雛形は1コマンドで作成できてしまう。例えば以下の通り。

$ create_project HelloAndroid org.papamitra.helloandroid --platform android-2.1 --scala-version 2.8.0.RC7 --activity HelloAndroid

作成されるディレクトリの構成はこんな感じ。

$ tree -n HelloAndroid
HelloAndroid/
├── project
│   ├── build
│   │   └── HelloAndroid.scala
│   ├── build.properties
│   └── plugins
│       └── Plugins.scala
├── src
│   ├── main
│   │   ├── AndroidManifest.xml
│   │   ├── assets
│   │   ├── java
│   │   ├── res
│   │   │   ├── drawable
│   │   │   │   └── app_icon.png
│   │   │   ├── layout
│   │   │   ├── values
│   │   │   │   └── strings.xml
│   │   │   └── xml
│   │   └── scala
│   │       └── Activity.scala
│   └── test
│       └── scala
│           └── Specs.scala
└── tests
    └── src
        └── main
            ├── AndroidManifest.xml
            ├── assets
            ├── res
            └── scala
                └── UnitTests.scala

sbtを実行すると、scalaやproguardなんかを勝手にダウンロードして環境を構築してくれる。

$ cd HelloAndroid
$ sbt

あとはsbtのプロンプトから

> compile

コンパイル

インストールは

> install-emulator
> install-device

上がエミュレータ用で下が実機用。