roboguice 2.0.jar有三個依賴包:guice-3.0-no_aop.jar,javax.inject-1.jar,jsr305-1.3.9.jar
roboguice 1.*.jar有一個依賴包:guice-2.0-no_aop.jar
2.0比1.*的優勢是:
提高了穩定性
支援Fragment
更簡潔易用
2.0與1.*的區別是:
2.0不在對Application進行重寫,原本1.*含有的RoboApplication在2.0中已不存在
2.0的模組綁定需要繼承AbstractModules,原本1.*中的AbstractAndroidModules不在存在
2.0增加了對Fragment的支援,所以進行android3.0以上版本的開發的時候,2.0可以更好地支援此屬性。
在開發應用時,有個原則是模組化,而模組與模組之間 要儘可能的降低耦合,
基於架構降低耦合的一個典型模式就是 依賴注入,在spring架構,Google的guice,以及Google基於android平台的roboguice架構,
都具有依賴注入功能,有了架構的依賴注入,我們就不必使用建構函式或者Factory 方法來執行個體化對象,而是由架構本身 根據類與類之間所描述的關係,自動注入。spring的反轉控制的本質就是 自下而上的依賴注入。
當然guice和roboguice有些地方是用到了一些Factory 方法的,但是程式不會依賴於工場方法來建立對象,只是架構所提供的Api對外部使用的一種支援,
RoboGuice是Guice根據android平台設計的架構,較少了繁瑣的尋找代碼,對象執行個體化等工作。下面分11個步驟全面說明RoboGuice的特性:
1.當一個類 有預設建構函式時,支援
@ Inject ClassName demo;
2.支援Android資源的注入:
@InjectView(R.id.XXX) TextView name;
@InjectResource(R.drawable.icon) Drawable icon;
3.支援Android標準API的注入:
@Inject ContentResolver contentResolver;
@Inject AssetManager assetManager;
@Inject Resources resources;
@Inject LocationManager locationManager;
@Inject WindowManager windowManager;
@Inject LayoutInflater layoutInflater;
@Inject ActivityManager activityManager;
@Inject PowerManager powerManager;
@Inject AlarmManager alarmManager;
@Inject NotificationManager notificationManager;
@Inject KeyguardManager keyguardManager;
@Inject SearchManager searchManager;
@Inject Vibrator vibrator;
@Inject ConnectivityManager connectivityManager;
@Inject WifiManager wifiManager;
@Inject InputMethodManager inputMethodManager;
@Inject SensorManager sensorManager;
@Inject Application application;
@Inject Context context;
4.多種實現的綁定:
例如:
介面:
public interface PhoneService{
public void call();
}
實現:
實現1:
public class PhoneStyleOne implements PhoneService{
public PhoneStyleOne() {
System.out.println("PhoneStyleOne");
}
@Override
public void call() {
System.out.println("PhoneStyleOne:PhoneStyleOne");
}
}
實現2:
public class PhoneStyleTwo implements PhoneService {
public PhoneStyleTwo() {
System.out.println("PhoneStyleTwo");
}
@Override
public void call() {
System.out.println("PhoneStyleTwo:PhoneStyleTwo");
}
}
該種情況下,有兩種綁定方式:
第一種:自訂註解,
定義註解:
@BindingAnnotation
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface PO {
//....
}
@BindingAnnotation
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface PW {
//....
}
綁定:
bind(PhoneService.class).annotatedWith(PO.class).to(PhoneStyleOne.class);
bind(PhoneService.class).annotatedWith(PW.class).to(PhoneStyleTwo.class);
注入:
@Inject @PO PhoneService ps1;
@Inject @PW PhoneService ps2;
第二種:使用Name註解標記
綁定:
bind(PhoneService.class).annotatedWith(Names.named("phOne")).to(PhoneStyleOne.class);
bind(PhoneService.class).annotatedWith(Names.named("phTwo")).to(PhoneStyleTwo.class);
注入:
@Inject @Named("phOne") PhoneService ps1;
@Inject @Named("phTwo") PhoneService ps2;
5.執行個體綁定:
執行個體綁定,一般的將綁定一些基本類型和字串類型,不建議將複雜類型綁定到特定的執行個體。
bind(Integer.class).annotatedWith(Names.named("width")).toInstance(10);
bind(String.class).annotatedWith(Names.named("name")).toInstance("zhangsan");
6.複雜類型執行個體的綁定:
由於RoboGuice官方不推薦使用 Instance綁定複雜類型,所以正確的方法應該是使用@ Providers,
定義:
在AbstractModule執行個體中,定義方法,並用@ Provides進行標註:
@Provides @Named("MyPhoneService")
PhoneService provideMyPhoneService(){
return new PhoneService() {
@Override
public void call() {
System.out.println(" Providers PhoneService");
}
};
}
@Provides @PO
PhoneService provideMyPhoneService1(){
return new PhoneService() {
@Override
public void call() {
System.out.println(" Providers PhoneService one");
}
};
}
注入:
@Inject @Named("MyPhoneService") PhoneService myservice;
@Inject @PO PhoneService ms1;
或者定義到Provider單獨實作類別中,這個類一定要實現roboguice的介面:
定義Provider:
public class ProviderString implements Provider<PhoneStyleTwo> {
@Override
public PhoneStyleTwo get() {
System.out.println("get PhoneStyleTwo");
return new PhoneStyleTwo();
}
}
綁定:
bind(PhoneStyleTwo.class).toProvider(ProviderString.class);
注入:
@Inject PhoneStyleTwo two;
7.單例:
RoboGuice允許在一定的範圍內重用類的執行個體,有兩個標記可以將一個類指定為單例:
@Singleton
@ContextScoped
8.預設是實現的第二種方式定義:
@ImplementedBy(Class)
public interface InterfaceOne{
void method();
}
與
bind(InterfaceOne.class).to(Class);等效,
如果同時存在@ ImplementedBy(Class)和bind,將優先使用bind中的實現。
@ProvidedBy(Provider.class)
public interface TransactionLog {
void method();
}
與bind(TransactionLog).toProvider(Class);
如果同時存在@ ProvidedBy(Class)和bind,將優先使用bind中的實現。
9.參數化型別的綁定:
使用TypeLiteral來建立此類型的綁定,
bind(new TypeLiteral<List<String>>(){}).toInstance(new ArrayList<String>());
或者使用@ Providers
@Provides
List<String> provideString()
{
return new LinkedList<String>();
}
10.註解總結:
@InjectExtra
@InjectPreference
@InjectResouece
@InjectView
@Inject
@SharedPreferencesName
此外,RoboGuice還提供了簡單的訊息publish/subscribe 機制,以及可以支援Dependency Injection的RoboThread, RoboAsyncTask ,RoboLooperThread 等,
11.RoboGuice對各種資源檔,及資料傳遞的支援:
@InjectView (R.id.styled_text) TextView styled_text;
@InjectView (R.id.plain_text) TextView plain_text;
@InjectView (R.id.res1) TextView res1;
@Inject Resources res;
@InjectResource(R.string.styled_text) String str;
@InjectExtra ("Extra2" ) String extra2;
@InjectExtra (value="Extra3" , optional=true) String extra3;
附上幾張有用的圖片:
本例練習為:http://files.cnblogs.com/Gordon-YangYiBao/roboguice.rar