2010年12月12日日曜日

RoboGuiceのInject関連のソース読んできた。

ぶっちゃけぼくはGoogle GuiceをつかったことがないのでRoboGuiceのソース読んでもこんなもんなのかなーという感じにしか読めなかったわけなのだがそれなりに面白かった。
(まだ全部はよんでいない)

RoboGuiceを使うこと自体にはGuiceの知識はそこまで必要ない(Springとか触ったことあるなら)
だけどRoboGuice自体Guice使って書かれてるので中身知りたくなった時点でGuiceの知識が必要になるからこんどGuice勉強してみる。

で、Injectionの話にもどる訳なんだけどまずRoboGuice固有のInjection用のannotationを並べてみる

@InjectExtra
@InjectPreference
@InjectResource
@InjectView

この4つ

一応書いておくと
@Retension(RUNTIME) ※1
@Targer(FIELD,PARAMETER,METHOD) ※2 です。(全部)

(※1 Runtimeはリフレクションつかってアクセスできるし、クラスファイルにもアノテーションの情報が残りますよって意味です。@Overrideなんかは@Retension=SOURCEなのでリフレクションつかってアノテーションの情報を取ってくることはできないし、クラスファイルにアノテーションの情報は残りません。コンパイル時に破棄されます)

(※2 フィールド変数、メソッドの引数、メソッドにこのアノテーションが付けられますよの意味)

さて、各アノテーションの詳細を書いてきます

1.@InjectExtra

@InjectExtraはString valueとBoolean optionalという二つの値を持っています。
このアノテーションはIntentによって呼び出されたActivityで呼び出される前にputExtra()で設定された値を取り出すとき(いつもならgetExtra()するとき)に使います。

下は一例(

@InjectExtra(value = "id")
Integer id;

(前回の記事にもちょろっと書いてありますけど、@InjectExtraを使う場所は基本的にはフィールド変数に対してです、と一応 (あとの3つも同様))

これでgetExtra("id")とか書いたときとおんなじようになりました。

で、うまくいったやったーとおもって終わりかと思えばoptionalってなんだったの?ということに
で調べてみると、どうやらデフォルト値を設定するかどうかを聞いてるようです(なにもしないとoptionalはfalseになっておりデフォルト値なんてないよってことになってるみたい)

optionalを含めて使ってみた

@InjectExtra(value = "id", optional = true)
Integer id = 0;


こうするともし"id"というkeyで取得できる値がなかったら0にしといてということになる。

ついでにvalueやoptionalとかの指定は省略して下のようにも書ける

@InjectExtra("id")
Integer id = 0;


で、この@InjectExtraの仕様で気をつけることがあって持ってくる値がnullであることを許容してくれません。
もしnullでもちゃんと持ってきてほしいとおもったら@Nullableをつけましょう。

@InjectExtra("id")
@Nullable
Integer id = 0;

これで@InjectExtraはおしまいです。
ちなみにたしか変数名と@InjectExtraのvalueは同じでなければならなかったはずなのでご注意を(確証はない。でもたぶんそうだったはず)

あとの三つですがoptionalがない(デフォルト値設定がない)というのとvalueの型が少し違うという以外@InjectExtraと特に違うところはありません
(@InjectPreferenceはRoboPreferenceActivityを継承したクラス内のみ使用可能というぐらいです)

一応使用例としてテキトーに書いたソースを下に貼っつけておきます。


class RoboWay extends RoboActivity { 
    @InjectView(R.id.name) TextView name; 
    @InjectView(R.id.thumbnail) ImageView thumbnail; 
    @InjectResource(R.drawable.icon) Drawable icon; 
    @InjectResource(R.string.app_name) String myName; 
    @InjectExtra("id") Integer id; 
    @InjectExtra("from") String from;

    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        name.setText( "Hello, " + myName ); 
    } 
}

2010年12月11日土曜日

RoboGuiceとかちょっと見てみた

いや、本当にまだ見てみただけ
今のところやったこと sampleのAstroboyの全ソース読んだぐらいです。

RoboGuiceのサイト
http://code.google.com/p/roboguice/

RoboGuiceってなーにって人用にちょっとだけ解説ー

一言で言うとandroid用のDIコンテナーです。
DIってなーにっていう方はJavaフレームワーク開発入門とか読んでみましょう。
まだ触るにははやいってことです(いや、僕も今読んでる途中ですけど)

どんなことができるか。
例えばいつもはこんな感じに書くコードを


// こんな感じ
Button myButton = (Button) findViewById(R.id.my_button);
次のような感じに書けます。

@InjectResource(R.id.my_button)
Button myButton;

アノテーション書けばかってにキャストして入れてくれるよってことですな。
でもまあ、これだけじゃ別にたいしたことないじゃんってやつですが、

LocationManager mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

とかいうのも
@Inject
LocationManager mLocationManager;


とかやればかってに初期化しといてくれます。
ちょっと便利

ほかにもたとえばIntentで自分がつくったActivityが起動されたときにsetExtra()でくっついてきた値を取るときにこんなふうに書けば取っといてくれます。


@InjectExtra("nameExtra")
protected String nameExtra;
意味はこれ
nameExtra=getIntent().getStringExtra("nameExtra")

あとよくありがちな@Nullableとかもあった。

androidによくあったResourceやIntent連携で起きるデータのやり取りとかのどうしてこうなったwという仕様(キャストが必要とか)をGuiceがやさしくしてくれる感じ

追記:上でやってたことはすべてField変数にたいしてです。

とりあえず見てみただけだからこのへんにしとく
詳しくは上のページにあるsampleのところにあるAstroboyを見るといいと思うのです。
astroboyは一時間もあれば読めると思うですよ(それぐらいRoboGuice君がやさしくしてくれた)

次回のRoboGuiceに関する記事の予定
RoboGuice使ってUnitTestやってみる
(Twitterで@vvakameさんがやれとかいってたので)
もしくは普通に導入手順とか書くかも(あとあと勉強会するときにもう一度調べるのめんどくさいから)

すこしBlogを一新したのです

いや、いろいろひどいことになってたのである程度戻しました。
そろそろBlog再開しますです