RoboGuiceやってみた

なんとなく知ってる

名前だけはなんとなく知ってた。やってる人を見た事はなかった。
いわく、DIとか出来るらしい。何それ?

http://code.google.com/p/roboguice/
XMLみたいなファイルに設定を書くのではなく、Javaコード上で設定するんだって。
コード補完やリファクタリングコンパイル時までにエラーが検出されるので偉いと思う。

やってみた

http://gist.github.com/560780
↑サンプルコード書くのめんどいんで今書いてるアプリをそのままこぴっぺ

動かす上で必要なことを軽く説明

MyApplication.java (http://gist.github.com/560780#file_my_application.java)

DIするためにアプリ起動時に呼び出さないといけないらしい
Module(DIの設定実体っぽい)とゆー物体を登録してまわります

MyModule.java (http://gist.github.com/560780#file_my_module.java)

ここではBitmapクラスについてDI要求されたら、BitmapFromUriExtraProviderていうプロバイダで解決しろって指定してます。
ContentProviderとは全然関係のない物体なんで注意です。

MainActivity.java (http://gist.github.com/560780#file_main_activity.java)

特にポイントなし
data.putExtra("mediaImageUri", pictUri); で、
content://media/external/images/media/332 的なUriを"mediaImageUri"で持たす

BitmapFromUriExtraProvider.java (http://gist.github.com/560780#file_bitmap_from_uri_extra_provider.java)

MainActivityから飛ばしたIntentはDotActivityに行きます。で、DotActivityではBitmapをDIしてくれと要求するコードが書いてあります(後述)
MyModuleで指定した通り、Bitmapに変換する処理をしてくれます。

@InjectExtra("mediaImageUri")
protected Uri mediaUri;

って書いてやると、RoboGuiceが勝手にIntentのExtrasから"mediaImageUri"に入ってるものを変数に詰めておいてくれます。
で、そこからBitmapに変換して返してやればいいので

  1. ContentResolverを介してビットマップを
  2. サイズ取得して
  3. Scale決めて
  4. 大きくても端末解像度〜端末解像度*2くらいのサイズに変換

してくれます。従来だったら受け取った先のActivity内で処理してやらなければいけなかったところですね。
また、WindowManagerが欲しかったので

@Inject
protected Activity act;

とかやってDIで詰めといてもらってます。自分がやってみたときはDotAcitivityが詰まってました。
ここらへん特にMyModuleに書いたわけでもなく適当に詰めといてくれるのが嬉しいですが、仕組みが分からなくてなんかキモいです。
ルックアップのルール的なものがあるんじゃないかなーとか思ってるんですが…。
なんもないとこからインスタンス作って詰めといてくれてるわけじゃないよね…?

DotActivity.java (http://gist.github.com/560780#file_dot_activity.java)
// Powered by BitmapFromUriExtraProvider
@Inject
private Bitmap mBGBitmap;

ここんところにBitmapFromUriExtraProviderで処理して作ったBitmapがちゅるちゅるぽんされます!パネェ!

AndroidManifest.xml (http://gist.github.com/560780#file_android_manifest.xml)
<application android:icon="@drawable/icon" android:label="@string/app_name"
 android:name=".MyApplication" android:debuggable="true">

android:name のとこが大事っぽい。これないとうまくInjectionできないらしくて死ぬ

追記

らしい。またひとつお利口さんになってしまった。ますいさんパネェ。

分かったこととか

  • MainActivityからDotActivityにIntent投げるだけでOutOfMemoryで死んだりしないまぁそれっぽいサイズでBitmap作って置いてくれる
    • Bitmap作成コードを毎回手で書かなくて済みそう
    • ロジックがProviderに自然に吐き出されたので見通しがよくなった
      • @Named アノテーションとかでExtras→Bitmapに変換する場合を制御してあげないと意図せず変換されて死ぬかも?
  • @InjectExtraはActivityでsetContentViewしたときに処理されるらしいので、もし指定のIDのViewが解決されなかったらその時点で死ぬ
    • OnClickでボタン押すまでわかんない… とかがないのでこれは利点なのでは?
  • 今のところ、Testの書き方がわからない… DI=Test ということで長く遠いTest坂を登り始めようとしたら階段なかった
  • コードの使い回しはすごい出来そう 各々が作っていってぷちDSL化してうぇ読めない…化しそうなほどに
  • RoboGuiceプロジェクト自体のテストコードがほとんどないっぽい
    • それどうなの…!!

誰かテストの書き方教えてください…!

らしいのできっとますいさんがなんとか(解決|粉砕)してくれるはず ^q^

09/05 02:07 追記

id:esmasui:20100904
ますいさんがテストを倒してくださいました!!
よりDIらしいテストを見せてやるから覚悟しろよぐへへへw とのことなので引き続き正座待機です。

09/02 21:45 追記

テスト用のクラスが1.0のjarに含まれてないので最新のを取ってきてみる
どうせ使わないから意味なかった。上記のますいさんのブログを参照のこと。

hg clone https://roboguice.googlecode.com/hg/ roboguice
cd roboguice/roboguice
mvn package

で出来た。ただ、最初はなんかmaps.jarねぇよ!とか言われたので

install:install-file -Dfile=$ANDROID_SDK_HOME/add-ons/google_apis-7_r01/libs/maps.jar -DgroupId=com.google.android.maps -DartifactId=maps -Dversion=3_r3 -Dpackaging=jar

とかしてやる必要があった。↓参照 versionあってないけどキニシナイ
http://code.google.com/p/roboguice/issues/detail?id=38

とりあえず1.0→1.1でGuiceActivityってクラスがRoboActivityってクラスに変更されてたりして泣いた。インターフェイス変えないでおくれよ…。
気のせいか起動が早くなった気がした… 多分気のせい。