本例實(shí)現(xiàn)的功能和例子 Android RoboGuice 使用指南(2):第一個(gè)例子Hello World 一樣,所不同的是本例使用 RoboGuice2.0 來實(shí)現(xiàn)。
http://wiki.jikexueyuan.com/project/android-roboguice/images/22.png" alt="" />
庫可以從 http://code.google.com/p/roboguice/ 下載,也可以從本站 下載
創(chuàng)建一個(gè)新 Android 項(xiàng)目,比如 GuiceDemo,目標(biāo)平臺(tái) Android1.5 以上。
http://wiki.jikexueyuan.com/project/android-roboguice/images/23.png" alt="" />
注:從 ADT17 開始,添加的 jar 文件需放在 libs 子目錄下,可以參見升級(jí)到 ADT 17 出現(xiàn) dalvikvm: Unable to resolve superclass 的問題
添加了對(duì)應(yīng) guice 和 roboguice 庫的引用之后,就可以開始編寫第一個(gè)使用 roboguice2 的例子。
使用 roboguice2 的步驟:
Roboguice2 中不在含有 RoboApplication 類,因此無需也不可能派生 RoboApplication 的子類。這里重復(fù)一下 HelloWorld 的 Layout 和類說明
<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:orientation=”vertical”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
>
<TextView
android:id=”@+id/hello”
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”@string/hello”
/>
</LinearLayout>
我們定義了一個(gè) TextView ,它的 id 為 hello.
假定這個(gè)應(yīng)用使用一個(gè) IGreetingService ,它有一個(gè)方法 getGreeting() 返回一個(gè)字符串,至于 IGreetingService 如何實(shí)現(xiàn),GuideDemo 不需要關(guān)心。
http://wiki.jikexueyuan.com/project/android-roboguice/images/24.png" alt="" />
Dependency injection 設(shè)計(jì)模式的一個(gè)核心原則為: Separate behavior from dependency resolution. 也就說將應(yīng)用需要實(shí)現(xiàn)的功能和其所依賴的服務(wù)或其它對(duì)象分離。 對(duì)本例來說 GuiceDemo 只要知道它依賴于 IGreetingService 服務(wù),至于 IGreetingService 有誰實(shí)現(xiàn)GuiceDemo 并不需要知道。
在 Roboguice 中使用 @Inject 來表示這種依賴關(guān)系。
public class GuiceDemo extends RoboActivity {
@InjectView (R.id.hello) TextView helloLabel;
@Inject IGreetingService greetingServce;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
helloLabel.setText(greetingServce.getGreetings());
}
}
代碼中沒有創(chuàng)建 greetingServce 對(duì)象的代碼(如 new xxx()) 和為 helloLabel 賦值的代碼。這些值都可以 Roboguice 自動(dòng)創(chuàng)建和賦值注入(Inject) 到變量中。
為了說明問題,我們?cè)诖a中添加兩個(gè)對(duì) getGreetings 的實(shí)現(xiàn),一個(gè)為HelloWorld, 一個(gè)為 HelloChina:
public class HelloChina implements IGreetingService{
@Override
public String getGreetings() {
return "Hello,China";
}
}
public class HelloWorld implements IGreetingService{
@Override
public String getGreetings() {
return "Hello,World";
}
}
在項(xiàng)目中添加一個(gè) GreetingModule (從 AbstractModule 派生而非 AbstractAndroidModule 類)重載 configure 方法:
public class GreetingModule extends AbstractAndroidModule{
@Override
protected void configure() {
bind(IGreetingService.class).to(HelloWorld.class);
//bind(IGreetingService.class).to(HelloChina.class);
}
}
將 IGreetingService 綁定到 HelloWorld 類。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="roboguice_modules">
<item>com.pstreets.guice.demo.GreetingModule</item>
</string-array>
</resources>
可以將 GreetingModule 綁定改為 HelloChina ,對(duì)比一下:
http://wiki.jikexueyuan.com/project/android-roboguice/images/25.png" alt="" />
通過改變 binding ,GuiceDemo 顯示了不同的結(jié)果,GuiceDemo 不依賴于具體的實(shí)現(xiàn),可以非常方便的改變接口的實(shí)現(xiàn)而無需更改 GuiceDemo 的代碼。大大降低了類于類之間的耦合性。