鍍金池/ 教程/ Android/ Binding Annotations
Just-in-time Bindings
Binding Annotations
Standard Injection
第一個(gè)例子 Hello World
Bindings 概述
Linked Bindings
如何綁定 generic 類型
@Provides Methods
RoboGuice 功能描述
概述
綜合示例 Astroboy
Inject Resources
Instance Bindings
Inject 自定義 View
Scopes
Provider Bindings
Untargetted Bindings
Inject Extra
第一個(gè)例子 Hello World
Inject Context
發(fā)送接收 Events
Inject View

Binding Annotations

有些情況需要將同一類型映射到不同的類實(shí)現(xiàn),還是使用繪圖的例子.

IShape, Rectangle, MyRectangle, MySquare, 有如下繼承關(guān)系:

http://wiki.jikexueyuan.com/project/android-roboguice/images/8.png" alt="" />

我們可能需要將 IShape 同時(shí)映射到 MyRectangle 和 MySquare ,這時(shí)可以使用 Binding Annotation 來(lái)實(shí)現(xiàn)。 這時(shí)使用類型和 annotation (標(biāo)注)可以唯一確定一個(gè) Binding。Type 和 annotation 對(duì)稱為 Key(鍵)。

為了同時(shí)使用 MyRectangle 和 MySequare,我們定義兩個(gè) annotation,如下

import com.google.inject.BindingAnnotation;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;

...
@BindingAnnotation
@Target({ FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
public @interface Rectangle {
}
...

@BindingAnnotation
@Target({ FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
public @interface Square {
}

定義了兩個(gè)標(biāo)注 @Rectangle, @Square, 至于 @BindingAnnotation,@Target,@Retention 你并不需要詳細(xì)了解,有興趣的可以參見 Java Annotation tutorial

簡(jiǎn)單的說(shuō)明如下:

  • @BindingAnnotation 通知這是一個(gè) Binding Annotation,如果將多個(gè)個(gè)標(biāo)注應(yīng)用到同一個(gè)元素時(shí),Guice 會(huì)報(bào)錯(cuò)。
  • @Target({FIELD, PARAMETER, METHOD}) 表示這個(gè)標(biāo)注可以應(yīng)用到類成員變量,函數(shù)的參數(shù)或時(shí)方法。
  • @Retention(RUNTIME) 表示這個(gè)標(biāo)注在程序運(yùn)行時(shí)可以使用 Reflection 讀取。

創(chuàng)建一個(gè) BindingAnnotationsDemo 用來(lái)繪制兩個(gè)圖形:

public class BindingAnnotationsDemo extends Graphics2DActivity{

 @Inject @Rectangle IShape  shape1;
 @Inject @Square IShape  shape2;

 protected void drawImage(){

 /**
 * The semi-opaque blue color in
 * the ARGB space (alpha is 0x78)
 */
 Color blueColor = new Color(0x780000ff,true);
 /**
 * The semi-opaque green color in the ARGB space (alpha is 0x78)
 */
 Color greenColor = new Color(0x7800ff00,true);

 graphics2D.clear(Color.WHITE);
 graphics2D.Reset();

 SolidBrush brush=new SolidBrush(blueColor);

 graphics2D.fill(brush,shape1);
 AffineTransform at = new AffineTransform();
 at.translate(20, 20);
 graphics2D.setAffineTransform(at);
 brush=new SolidBrush(greenColor);
 graphics2D.fill(brush,shape2);

 }

}

使用標(biāo)注將 shape1 綁定到 MyRectangle, shape2 綁定到 MySquare,對(duì)應(yīng)的 Module 定義如下:

public class Graphics2DModule extends AbstractAndroidModule{

 @Override
 protected void configure() {

 bind(IShape.class)
 .annotatedWith(Rectangle.class)
 .to(MyRectangle.class);

 bind(IShape.class)
 .annotatedWith(Square.class)
 .to(MySquare.class);

 }
}

http://wiki.jikexueyuan.com/project/android-roboguice/images/9.png" alt="" />

Inject 可以應(yīng)用到 Field (成員變量),Parameter (參數(shù))或 Method (方法),前面的例子都是應(yīng)用到 Field 上,如果應(yīng)用到參數(shù)可以有如下形式:

@Inject
public IShape getShape(@Rectangle IShape shape){
...
}

如果你不想自定義 Annotation,可以使用 Guice 自帶的 @Name 標(biāo)注來(lái)解決同一類型綁定到不同實(shí)現(xiàn)的問(wèn)題。

修改上面代碼:

//@Inject @Rectangle IShape  shape1;
//@Inject @Square IShape  shape2;

@Inject @Named("Rectangle") IShape shape1;
@Inject @Named("Square") IShape shape2;

修改綁定如下:

//bind(IShape.class)
//.annotatedWith(Rectangle.class)
//.to(MyRectangle.class);

//bind(IShape.class)
//.annotatedWith(Square.class)
//.to(MySquare.class);

bind(IShape.class)
 .annotatedWith(Names.named("Rectangle"))
 .to(MyRectangle.class);
bind(IShape.class)
 .annotatedWith(Names.named("Square"))
 .to(MySquare.class);

這種方法簡(jiǎn)單,但編譯器無(wú)法檢測(cè)字符串,比如將 ”Square” 錯(cuò)寫為 ”Sqare”,編譯器無(wú)法查出這個(gè)錯(cuò)誤,此時(shí)到運(yùn)行時(shí)才可能發(fā)現(xiàn) shape2 無(wú)法注入,因此建議盡量少用 Named.